blob: 3110bb06575bdc46c0e9d9a94a30bc2bce5322b4 [file] [log] [blame]
Minkyu Kangb1b24682011-01-24 15:22:23 +09001/*
2 * Copyright (C) 2010 Samsung Electronics
3 * Minkyu Kang <mk7.kang@samsung.com>
4 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Minkyu Kangb1b24682011-01-24 15:22:23 +09006 */
7
8#include <common.h>
9#include <asm/io.h>
10#include <asm/arch/clock.h>
11#include <asm/arch/clk.h>
Hatim RVe6365b62012-11-02 01:15:34 +000012#include <asm/arch/periph.h>
Minkyu Kangb1b24682011-01-24 15:22:23 +090013
Minkyu Kang368588e2013-07-05 19:08:33 +090014#define PLL_DIV_1024 1024
15#define PLL_DIV_65535 65535
16#define PLL_DIV_65536 65536
17
Padmavathi Venna37feb7b2013-03-28 04:32:21 +000018/* *
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 int8_t src_bit;
24 int8_t div_bit;
25 int8_t prediv_bit;
26};
27
28/* src_bit div_bit prediv_bit */
Minkyu Kang30e472f2014-01-29 17:03:58 +090029static struct clk_bit_info clk_bit_info[] = {
Padmavathi Venna37feb7b2013-03-28 04:32:21 +000030 {0, 0, -1},
31 {4, 4, -1},
32 {8, 8, -1},
33 {12, 12, -1},
34 {0, 0, 8},
35 {4, 16, 24},
36 {8, 0, 8},
37 {12, 16, 24},
38 {-1, -1, -1},
39 {16, 0, 8},
40 {20, 16, 24},
41 {24, 0, 8},
42 {0, 0, 4},
43 {4, 12, 16},
44 {-1, -1, -1},
45 {-1, -1, -1},
46 {-1, 24, 0},
47 {-1, 24, 0},
48 {-1, 24, 0},
49 {-1, 24, 0},
50 {-1, 24, 0},
51 {-1, 24, 0},
52 {-1, 24, 0},
53 {-1, 24, 0},
54 {24, 0, -1},
55 {24, 0, -1},
56 {24, 0, -1},
57 {24, 0, -1},
58 {24, 0, -1},
59};
60
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +000061/* Epll Clock division values to achive different frequency output */
62static struct set_epll_con_val exynos5_epll_div[] = {
63 { 192000000, 0, 48, 3, 1, 0 },
64 { 180000000, 0, 45, 3, 1, 0 },
65 { 73728000, 1, 73, 3, 3, 47710 },
66 { 67737600, 1, 90, 4, 3, 20762 },
67 { 49152000, 0, 49, 3, 3, 9961 },
68 { 45158400, 0, 45, 3, 3, 10381 },
69 { 180633600, 0, 45, 3, 1, 10381 }
70};
71
Minkyu Kang1a055aa2012-10-15 01:58:00 +000072/* exynos: return pll clock frequency */
73static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
Minkyu Kangb1b24682011-01-24 15:22:23 +090074{
Minkyu Kang1a055aa2012-10-15 01:58:00 +000075 unsigned long m, p, s = 0, mask, fout;
Minkyu Kang368588e2013-07-05 19:08:33 +090076 unsigned int div;
Minkyu Kangb1b24682011-01-24 15:22:23 +090077 unsigned int freq;
Minkyu Kangb1b24682011-01-24 15:22:23 +090078 /*
79 * APLL_CON: MIDV [25:16]
80 * MPLL_CON: MIDV [25:16]
81 * EPLL_CON: MIDV [24:16]
82 * VPLL_CON: MIDV [24:16]
Minkyu Kang1a055aa2012-10-15 01:58:00 +000083 * BPLL_CON: MIDV [25:16]: Exynos5
Minkyu Kangb1b24682011-01-24 15:22:23 +090084 */
Ajay Kumar914af872014-09-05 16:53:32 +053085 if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL ||
86 pllreg == SPLL)
Minkyu Kangb1b24682011-01-24 15:22:23 +090087 mask = 0x3ff;
88 else
89 mask = 0x1ff;
90
91 m = (r >> 16) & mask;
92
93 /* PDIV [13:8] */
94 p = (r >> 8) & 0x3f;
95 /* SDIV [2:0] */
96 s = r & 0x7;
97
Chander Kashyap6a870e12012-02-05 23:01:45 +000098 freq = CONFIG_SYS_CLK_FREQ;
Minkyu Kangb1b24682011-01-24 15:22:23 +090099
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530100 if (pllreg == EPLL || pllreg == RPLL) {
Minkyu Kangb1b24682011-01-24 15:22:23 +0900101 k = k & 0xffff;
102 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
Minkyu Kang368588e2013-07-05 19:08:33 +0900103 fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s)));
Minkyu Kangb1b24682011-01-24 15:22:23 +0900104 } else if (pllreg == VPLL) {
105 k = k & 0xfff;
Minkyu Kang368588e2013-07-05 19:08:33 +0900106
107 /*
108 * Exynos4210
109 * FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV)
110 *
111 * Exynos4412
112 * FOUT = (MDIV + K / 65535) * FIN / (PDIV * 2^SDIV)
113 *
114 * Exynos5250
115 * FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV)
116 */
117 if (proid_is_exynos4210())
118 div = PLL_DIV_1024;
119 else if (proid_is_exynos4412())
120 div = PLL_DIV_65535;
Akshay Saraswat9fba7b42014-11-13 22:38:15 +0530121 else if (proid_is_exynos5250() || proid_is_exynos5420()
122 || proid_is_exynos5800())
Minkyu Kang368588e2013-07-05 19:08:33 +0900123 div = PLL_DIV_65536;
124 else
125 return 0;
126
127 fout = (m + k / div) * (freq / (p * (1 << s)));
Minkyu Kangb1b24682011-01-24 15:22:23 +0900128 } else {
Minkyu Kang368588e2013-07-05 19:08:33 +0900129 /*
Łukasz Majewski326c4592013-07-12 19:08:25 +0200130 * Exynos4412 / Exynos5250
Minkyu Kang368588e2013-07-05 19:08:33 +0900131 * FOUT = MDIV * FIN / (PDIV * 2^SDIV)
132 *
Łukasz Majewski326c4592013-07-12 19:08:25 +0200133 * Exynos4210
Minkyu Kang368588e2013-07-05 19:08:33 +0900134 * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1))
135 */
136 if (proid_is_exynos4210())
Minkyu Kang368588e2013-07-05 19:08:33 +0900137 fout = m * (freq / (p * (1 << (s - 1))));
Łukasz Majewski326c4592013-07-12 19:08:25 +0200138 else
139 fout = m * (freq / (p * (1 << s)));
Minkyu Kangb1b24682011-01-24 15:22:23 +0900140 }
Minkyu Kangb1b24682011-01-24 15:22:23 +0900141 return fout;
142}
143
Minkyu Kang1a055aa2012-10-15 01:58:00 +0000144/* exynos4: return pll clock frequency */
145static unsigned long exynos4_get_pll_clk(int pllreg)
146{
147 struct exynos4_clock *clk =
148 (struct exynos4_clock *)samsung_get_base_clock();
149 unsigned long r, k = 0;
150
151 switch (pllreg) {
152 case APLL:
153 r = readl(&clk->apll_con0);
154 break;
155 case MPLL:
156 r = readl(&clk->mpll_con0);
157 break;
158 case EPLL:
159 r = readl(&clk->epll_con0);
160 k = readl(&clk->epll_con1);
161 break;
162 case VPLL:
163 r = readl(&clk->vpll_con0);
164 k = readl(&clk->vpll_con1);
165 break;
166 default:
167 printf("Unsupported PLL (%d)\n", pllreg);
168 return 0;
169 }
170
171 return exynos_get_pll_clk(pllreg, r, k);
172}
173
Chander Kashyap400ab162012-10-07 01:43:17 +0000174/* exynos4x12: return pll clock frequency */
175static unsigned long exynos4x12_get_pll_clk(int pllreg)
176{
177 struct exynos4x12_clock *clk =
178 (struct exynos4x12_clock *)samsung_get_base_clock();
179 unsigned long r, k = 0;
180
181 switch (pllreg) {
182 case APLL:
183 r = readl(&clk->apll_con0);
184 break;
185 case MPLL:
186 r = readl(&clk->mpll_con0);
187 break;
188 case EPLL:
189 r = readl(&clk->epll_con0);
190 k = readl(&clk->epll_con1);
191 break;
192 case VPLL:
193 r = readl(&clk->vpll_con0);
194 k = readl(&clk->vpll_con1);
195 break;
196 default:
197 printf("Unsupported PLL (%d)\n", pllreg);
198 return 0;
199 }
200
201 return exynos_get_pll_clk(pllreg, r, k);
202}
203
Chander Kashyap34076a02012-02-05 23:01:46 +0000204/* exynos5: return pll clock frequency */
205static unsigned long exynos5_get_pll_clk(int pllreg)
206{
207 struct exynos5_clock *clk =
208 (struct exynos5_clock *)samsung_get_base_clock();
Minkyu Kang1a055aa2012-10-15 01:58:00 +0000209 unsigned long r, k = 0, fout;
210 unsigned int pll_div2_sel, fout_sel;
Chander Kashyap34076a02012-02-05 23:01:46 +0000211
212 switch (pllreg) {
213 case APLL:
214 r = readl(&clk->apll_con0);
215 break;
216 case MPLL:
217 r = readl(&clk->mpll_con0);
218 break;
219 case EPLL:
220 r = readl(&clk->epll_con0);
221 k = readl(&clk->epll_con1);
222 break;
223 case VPLL:
224 r = readl(&clk->vpll_con0);
225 k = readl(&clk->vpll_con1);
226 break;
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000227 case BPLL:
228 r = readl(&clk->bpll_con0);
229 break;
Chander Kashyap34076a02012-02-05 23:01:46 +0000230 default:
231 printf("Unsupported PLL (%d)\n", pllreg);
232 return 0;
233 }
234
Minkyu Kang1a055aa2012-10-15 01:58:00 +0000235 fout = exynos_get_pll_clk(pllreg, r, k);
Chander Kashyap34076a02012-02-05 23:01:46 +0000236
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000237 /* According to the user manual, in EVT1 MPLL and BPLL always gives
Rajeshwari Shinde7b9afce2012-07-03 20:02:57 +0000238 * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000239 if (pllreg == MPLL || pllreg == BPLL) {
Rajeshwari Shinde7b9afce2012-07-03 20:02:57 +0000240 pll_div2_sel = readl(&clk->pll_div2_sel);
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000241
242 switch (pllreg) {
243 case MPLL:
244 fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
245 & MPLL_FOUT_SEL_MASK;
246 break;
247 case BPLL:
248 fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
249 & BPLL_FOUT_SEL_MASK;
250 break;
Jaehoon Chung0fc779c2012-07-09 21:20:34 +0000251 default:
252 fout_sel = -1;
253 break;
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000254 }
255
256 if (fout_sel == 0)
Rajeshwari Shinde7b9afce2012-07-03 20:02:57 +0000257 fout /= 2;
258 }
259
Chander Kashyap34076a02012-02-05 23:01:46 +0000260 return fout;
261}
262
Padmavathi Venna37feb7b2013-03-28 04:32:21 +0000263static unsigned long exynos5_get_periph_rate(int peripheral)
264{
265 struct clk_bit_info *bit_info = &clk_bit_info[peripheral];
266 unsigned long sclk, sub_clk;
267 unsigned int src, div, sub_div;
268 struct exynos5_clock *clk =
269 (struct exynos5_clock *)samsung_get_base_clock();
270
271 switch (peripheral) {
272 case PERIPH_ID_UART0:
273 case PERIPH_ID_UART1:
274 case PERIPH_ID_UART2:
275 case PERIPH_ID_UART3:
276 src = readl(&clk->src_peric0);
277 div = readl(&clk->div_peric0);
278 break;
279 case PERIPH_ID_PWM0:
280 case PERIPH_ID_PWM1:
281 case PERIPH_ID_PWM2:
282 case PERIPH_ID_PWM3:
283 case PERIPH_ID_PWM4:
284 src = readl(&clk->src_peric0);
285 div = readl(&clk->div_peric3);
286 break;
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +0530287 case PERIPH_ID_I2S0:
288 src = readl(&clk->src_mau);
289 div = readl(&clk->div_mau);
Padmavathi Venna37feb7b2013-03-28 04:32:21 +0000290 case PERIPH_ID_SPI0:
291 case PERIPH_ID_SPI1:
292 src = readl(&clk->src_peric1);
293 div = readl(&clk->div_peric1);
294 break;
295 case PERIPH_ID_SPI2:
296 src = readl(&clk->src_peric1);
297 div = readl(&clk->div_peric2);
298 break;
299 case PERIPH_ID_SPI3:
300 case PERIPH_ID_SPI4:
301 src = readl(&clk->sclk_src_isp);
302 div = readl(&clk->sclk_div_isp);
303 break;
304 case PERIPH_ID_SDMMC0:
305 case PERIPH_ID_SDMMC1:
306 case PERIPH_ID_SDMMC2:
307 case PERIPH_ID_SDMMC3:
308 src = readl(&clk->src_fsys);
309 div = readl(&clk->div_fsys1);
310 break;
311 case PERIPH_ID_I2C0:
312 case PERIPH_ID_I2C1:
313 case PERIPH_ID_I2C2:
314 case PERIPH_ID_I2C3:
315 case PERIPH_ID_I2C4:
316 case PERIPH_ID_I2C5:
317 case PERIPH_ID_I2C6:
318 case PERIPH_ID_I2C7:
319 sclk = exynos5_get_pll_clk(MPLL);
320 sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit)
321 & 0x7) + 1;
322 div = ((readl(&clk->div_top0) >> bit_info->prediv_bit)
323 & 0x7) + 1;
324 return (sclk / sub_div) / div;
325 default:
326 debug("%s: invalid peripheral %d", __func__, peripheral);
327 return -1;
328 };
329
330 src = (src >> bit_info->src_bit) & 0xf;
331
332 switch (src) {
333 case EXYNOS_SRC_MPLL:
334 sclk = exynos5_get_pll_clk(MPLL);
335 break;
336 case EXYNOS_SRC_EPLL:
337 sclk = exynos5_get_pll_clk(EPLL);
338 break;
339 case EXYNOS_SRC_VPLL:
340 sclk = exynos5_get_pll_clk(VPLL);
341 break;
342 default:
343 return 0;
344 }
345
346 /* Ratio clock division for this peripheral */
347 sub_div = (div >> bit_info->div_bit) & 0xf;
348 sub_clk = sclk / (sub_div + 1);
349
350 /* Pre-ratio clock division for SDMMC0 and 2 */
351 if (peripheral == PERIPH_ID_SDMMC0 || peripheral == PERIPH_ID_SDMMC2) {
352 div = (div >> bit_info->prediv_bit) & 0xff;
353 return sub_clk / (div + 1);
354 }
355
356 return sub_clk;
357}
358
359unsigned long clock_get_periph_rate(int peripheral)
360{
361 if (cpu_is_exynos5())
362 return exynos5_get_periph_rate(peripheral);
363 else
364 return 0;
365}
366
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530367/* exynos5420: return pll clock frequency */
368static unsigned long exynos5420_get_pll_clk(int pllreg)
369{
370 struct exynos5420_clock *clk =
371 (struct exynos5420_clock *)samsung_get_base_clock();
372 unsigned long r, k = 0;
373
374 switch (pllreg) {
375 case APLL:
376 r = readl(&clk->apll_con0);
377 break;
378 case MPLL:
379 r = readl(&clk->mpll_con0);
380 break;
381 case EPLL:
382 r = readl(&clk->epll_con0);
383 k = readl(&clk->epll_con1);
384 break;
385 case VPLL:
386 r = readl(&clk->vpll_con0);
387 k = readl(&clk->vpll_con1);
388 break;
389 case BPLL:
390 r = readl(&clk->bpll_con0);
391 break;
392 case RPLL:
393 r = readl(&clk->rpll_con0);
394 k = readl(&clk->rpll_con1);
395 break;
Ajay Kumar914af872014-09-05 16:53:32 +0530396 case SPLL:
397 r = readl(&clk->spll_con0);
398 break;
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530399 default:
400 printf("Unsupported PLL (%d)\n", pllreg);
401 return 0;
402 }
403
404 return exynos_get_pll_clk(pllreg, r, k);
405}
406
Chander Kashyap4131a772011-12-06 23:34:12 +0000407/* exynos4: return ARM clock frequency */
408static unsigned long exynos4_get_arm_clk(void)
Minkyu Kangb1b24682011-01-24 15:22:23 +0900409{
Chander Kashyap4131a772011-12-06 23:34:12 +0000410 struct exynos4_clock *clk =
411 (struct exynos4_clock *)samsung_get_base_clock();
Minkyu Kangb1b24682011-01-24 15:22:23 +0900412 unsigned long div;
Chander Kashyap3c7721f2011-12-18 22:56:44 +0000413 unsigned long armclk;
414 unsigned int core_ratio;
415 unsigned int core2_ratio;
Minkyu Kangb1b24682011-01-24 15:22:23 +0900416
417 div = readl(&clk->div_cpu0);
418
Chander Kashyap3c7721f2011-12-18 22:56:44 +0000419 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
420 core_ratio = (div >> 0) & 0x7;
421 core2_ratio = (div >> 28) & 0x7;
Minkyu Kangb1b24682011-01-24 15:22:23 +0900422
Chander Kashyap3c7721f2011-12-18 22:56:44 +0000423 armclk = get_pll_clk(APLL) / (core_ratio + 1);
424 armclk /= (core2_ratio + 1);
Minkyu Kangb1b24682011-01-24 15:22:23 +0900425
Chander Kashyap3c7721f2011-12-18 22:56:44 +0000426 return armclk;
Minkyu Kangb1b24682011-01-24 15:22:23 +0900427}
428
Chander Kashyap400ab162012-10-07 01:43:17 +0000429/* exynos4x12: return ARM clock frequency */
430static unsigned long exynos4x12_get_arm_clk(void)
431{
432 struct exynos4x12_clock *clk =
433 (struct exynos4x12_clock *)samsung_get_base_clock();
434 unsigned long div;
435 unsigned long armclk;
436 unsigned int core_ratio;
437 unsigned int core2_ratio;
438
439 div = readl(&clk->div_cpu0);
440
441 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
442 core_ratio = (div >> 0) & 0x7;
443 core2_ratio = (div >> 28) & 0x7;
444
445 armclk = get_pll_clk(APLL) / (core_ratio + 1);
446 armclk /= (core2_ratio + 1);
447
448 return armclk;
449}
450
Chander Kashyap34076a02012-02-05 23:01:46 +0000451/* exynos5: return ARM clock frequency */
452static unsigned long exynos5_get_arm_clk(void)
453{
454 struct exynos5_clock *clk =
455 (struct exynos5_clock *)samsung_get_base_clock();
456 unsigned long div;
457 unsigned long armclk;
458 unsigned int arm_ratio;
459 unsigned int arm2_ratio;
460
461 div = readl(&clk->div_cpu0);
462
463 /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
464 arm_ratio = (div >> 0) & 0x7;
465 arm2_ratio = (div >> 28) & 0x7;
466
467 armclk = get_pll_clk(APLL) / (arm_ratio + 1);
468 armclk /= (arm2_ratio + 1);
469
470 return armclk;
471}
472
Chander Kashyap4131a772011-12-06 23:34:12 +0000473/* exynos4: return pwm clock frequency */
474static unsigned long exynos4_get_pwm_clk(void)
Minkyu Kangb1b24682011-01-24 15:22:23 +0900475{
Chander Kashyap4131a772011-12-06 23:34:12 +0000476 struct exynos4_clock *clk =
477 (struct exynos4_clock *)samsung_get_base_clock();
Minkyu Kangb1b24682011-01-24 15:22:23 +0900478 unsigned long pclk, sclk;
479 unsigned int sel;
480 unsigned int ratio;
481
Minkyu Kang69b28242011-05-18 16:57:55 +0900482 if (s5p_get_cpu_rev() == 0) {
483 /*
484 * CLK_SRC_PERIL0
485 * PWM_SEL [27:24]
486 */
487 sel = readl(&clk->src_peril0);
488 sel = (sel >> 24) & 0xf;
Minkyu Kangb1b24682011-01-24 15:22:23 +0900489
Minkyu Kang69b28242011-05-18 16:57:55 +0900490 if (sel == 0x6)
491 sclk = get_pll_clk(MPLL);
492 else if (sel == 0x7)
493 sclk = get_pll_clk(EPLL);
494 else if (sel == 0x8)
495 sclk = get_pll_clk(VPLL);
496 else
497 return 0;
498
499 /*
500 * CLK_DIV_PERIL3
501 * PWM_RATIO [3:0]
502 */
503 ratio = readl(&clk->div_peril3);
504 ratio = ratio & 0xf;
505 } else if (s5p_get_cpu_rev() == 1) {
Minkyu Kangb1b24682011-01-24 15:22:23 +0900506 sclk = get_pll_clk(MPLL);
Minkyu Kang69b28242011-05-18 16:57:55 +0900507 ratio = 8;
508 } else
Minkyu Kangb1b24682011-01-24 15:22:23 +0900509 return 0;
510
Minkyu Kangb1b24682011-01-24 15:22:23 +0900511 pclk = sclk / (ratio + 1);
512
513 return pclk;
514}
515
Chander Kashyap400ab162012-10-07 01:43:17 +0000516/* exynos4x12: return pwm clock frequency */
517static unsigned long exynos4x12_get_pwm_clk(void)
518{
519 unsigned long pclk, sclk;
520 unsigned int ratio;
521
522 sclk = get_pll_clk(MPLL);
523 ratio = 8;
524
525 pclk = sclk / (ratio + 1);
526
527 return pclk;
528}
529
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530530/* exynos5420: return pwm clock frequency */
531static unsigned long exynos5420_get_pwm_clk(void)
532{
533 struct exynos5420_clock *clk =
534 (struct exynos5420_clock *)samsung_get_base_clock();
535 unsigned long pclk, sclk;
536 unsigned int ratio;
537
538 /*
539 * CLK_DIV_PERIC0
540 * PWM_RATIO [31:28]
541 */
542 ratio = readl(&clk->div_peric0);
543 ratio = (ratio >> 28) & 0xf;
544 sclk = get_pll_clk(MPLL);
545
546 pclk = sclk / (ratio + 1);
547
548 return pclk;
549}
550
Chander Kashyap4131a772011-12-06 23:34:12 +0000551/* exynos4: return uart clock frequency */
552static unsigned long exynos4_get_uart_clk(int dev_index)
Minkyu Kangb1b24682011-01-24 15:22:23 +0900553{
Chander Kashyap4131a772011-12-06 23:34:12 +0000554 struct exynos4_clock *clk =
555 (struct exynos4_clock *)samsung_get_base_clock();
Minkyu Kangb1b24682011-01-24 15:22:23 +0900556 unsigned long uclk, sclk;
557 unsigned int sel;
558 unsigned int ratio;
559
560 /*
561 * CLK_SRC_PERIL0
562 * UART0_SEL [3:0]
563 * UART1_SEL [7:4]
564 * UART2_SEL [8:11]
565 * UART3_SEL [12:15]
566 * UART4_SEL [16:19]
567 * UART5_SEL [23:20]
568 */
569 sel = readl(&clk->src_peril0);
570 sel = (sel >> (dev_index << 2)) & 0xf;
571
572 if (sel == 0x6)
573 sclk = get_pll_clk(MPLL);
574 else if (sel == 0x7)
575 sclk = get_pll_clk(EPLL);
576 else if (sel == 0x8)
577 sclk = get_pll_clk(VPLL);
578 else
579 return 0;
580
581 /*
582 * CLK_DIV_PERIL0
583 * UART0_RATIO [3:0]
584 * UART1_RATIO [7:4]
585 * UART2_RATIO [8:11]
586 * UART3_RATIO [12:15]
587 * UART4_RATIO [16:19]
588 * UART5_RATIO [23:20]
589 */
590 ratio = readl(&clk->div_peril0);
591 ratio = (ratio >> (dev_index << 2)) & 0xf;
592
593 uclk = sclk / (ratio + 1);
594
595 return uclk;
596}
597
Chander Kashyap400ab162012-10-07 01:43:17 +0000598/* exynos4x12: return uart clock frequency */
599static unsigned long exynos4x12_get_uart_clk(int dev_index)
600{
601 struct exynos4x12_clock *clk =
602 (struct exynos4x12_clock *)samsung_get_base_clock();
603 unsigned long uclk, sclk;
604 unsigned int sel;
605 unsigned int ratio;
606
607 /*
608 * CLK_SRC_PERIL0
609 * UART0_SEL [3:0]
610 * UART1_SEL [7:4]
611 * UART2_SEL [8:11]
612 * UART3_SEL [12:15]
613 * UART4_SEL [16:19]
614 */
615 sel = readl(&clk->src_peril0);
616 sel = (sel >> (dev_index << 2)) & 0xf;
617
618 if (sel == 0x6)
619 sclk = get_pll_clk(MPLL);
620 else if (sel == 0x7)
621 sclk = get_pll_clk(EPLL);
622 else if (sel == 0x8)
623 sclk = get_pll_clk(VPLL);
624 else
625 return 0;
626
627 /*
628 * CLK_DIV_PERIL0
629 * UART0_RATIO [3:0]
630 * UART1_RATIO [7:4]
631 * UART2_RATIO [8:11]
632 * UART3_RATIO [12:15]
633 * UART4_RATIO [16:19]
634 */
635 ratio = readl(&clk->div_peril0);
636 ratio = (ratio >> (dev_index << 2)) & 0xf;
637
638 uclk = sclk / (ratio + 1);
639
640 return uclk;
641}
642
Chander Kashyap34076a02012-02-05 23:01:46 +0000643/* exynos5: return uart clock frequency */
644static unsigned long exynos5_get_uart_clk(int dev_index)
645{
646 struct exynos5_clock *clk =
647 (struct exynos5_clock *)samsung_get_base_clock();
648 unsigned long uclk, sclk;
649 unsigned int sel;
650 unsigned int ratio;
651
652 /*
653 * CLK_SRC_PERIC0
654 * UART0_SEL [3:0]
655 * UART1_SEL [7:4]
656 * UART2_SEL [8:11]
657 * UART3_SEL [12:15]
658 * UART4_SEL [16:19]
659 * UART5_SEL [23:20]
660 */
661 sel = readl(&clk->src_peric0);
662 sel = (sel >> (dev_index << 2)) & 0xf;
663
664 if (sel == 0x6)
665 sclk = get_pll_clk(MPLL);
666 else if (sel == 0x7)
667 sclk = get_pll_clk(EPLL);
668 else if (sel == 0x8)
669 sclk = get_pll_clk(VPLL);
670 else
671 return 0;
672
673 /*
674 * CLK_DIV_PERIC0
675 * UART0_RATIO [3:0]
676 * UART1_RATIO [7:4]
677 * UART2_RATIO [8:11]
678 * UART3_RATIO [12:15]
679 * UART4_RATIO [16:19]
680 * UART5_RATIO [23:20]
681 */
682 ratio = readl(&clk->div_peric0);
683 ratio = (ratio >> (dev_index << 2)) & 0xf;
684
685 uclk = sclk / (ratio + 1);
686
687 return uclk;
688}
689
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530690/* exynos5420: return uart clock frequency */
691static unsigned long exynos5420_get_uart_clk(int dev_index)
692{
693 struct exynos5420_clock *clk =
694 (struct exynos5420_clock *)samsung_get_base_clock();
695 unsigned long uclk, sclk;
696 unsigned int sel;
697 unsigned int ratio;
698
699 /*
700 * CLK_SRC_PERIC0
701 * UART0_SEL [6:4]
702 * UART1_SEL [10:8]
703 * UART2_SEL [14:12]
704 * UART3_SEL [18:16]
705 * generalised calculation as follows
706 * sel = (sel >> ((dev_index * 4) + 4)) & mask;
707 */
708 sel = readl(&clk->src_peric0);
709 sel = (sel >> ((dev_index * 4) + 4)) & 0x7;
710
711 if (sel == 0x3)
712 sclk = get_pll_clk(MPLL);
713 else if (sel == 0x6)
714 sclk = get_pll_clk(EPLL);
715 else if (sel == 0x7)
716 sclk = get_pll_clk(RPLL);
717 else
718 return 0;
719
720 /*
721 * CLK_DIV_PERIC0
722 * UART0_RATIO [11:8]
723 * UART1_RATIO [15:12]
724 * UART2_RATIO [19:16]
725 * UART3_RATIO [23:20]
726 * generalised calculation as follows
727 * ratio = (ratio >> ((dev_index * 4) + 8)) & mask;
728 */
729 ratio = readl(&clk->div_peric0);
730 ratio = (ratio >> ((dev_index * 4) + 8)) & 0xf;
731
732 uclk = sclk / (ratio + 1);
733
734 return uclk;
735}
736
Jaehoon Chung8788e062012-12-27 22:30:32 +0000737static unsigned long exynos4_get_mmc_clk(int dev_index)
738{
739 struct exynos4_clock *clk =
740 (struct exynos4_clock *)samsung_get_base_clock();
741 unsigned long uclk, sclk;
742 unsigned int sel, ratio, pre_ratio;
Amare1df6282013-04-27 11:42:56 +0530743 int shift = 0;
Jaehoon Chung8788e062012-12-27 22:30:32 +0000744
745 sel = readl(&clk->src_fsys);
746 sel = (sel >> (dev_index << 2)) & 0xf;
747
748 if (sel == 0x6)
749 sclk = get_pll_clk(MPLL);
750 else if (sel == 0x7)
751 sclk = get_pll_clk(EPLL);
752 else if (sel == 0x8)
753 sclk = get_pll_clk(VPLL);
754 else
755 return 0;
756
757 switch (dev_index) {
758 case 0:
759 case 1:
760 ratio = readl(&clk->div_fsys1);
761 pre_ratio = readl(&clk->div_fsys1);
762 break;
763 case 2:
764 case 3:
765 ratio = readl(&clk->div_fsys2);
766 pre_ratio = readl(&clk->div_fsys2);
767 break;
768 case 4:
769 ratio = readl(&clk->div_fsys3);
770 pre_ratio = readl(&clk->div_fsys3);
771 break;
772 default:
773 return 0;
774 }
775
776 if (dev_index == 1 || dev_index == 3)
777 shift = 16;
778
779 ratio = (ratio >> shift) & 0xf;
780 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
781 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
782
783 return uclk;
784}
785
786static unsigned long exynos5_get_mmc_clk(int dev_index)
787{
788 struct exynos5_clock *clk =
789 (struct exynos5_clock *)samsung_get_base_clock();
790 unsigned long uclk, sclk;
791 unsigned int sel, ratio, pre_ratio;
Amare1df6282013-04-27 11:42:56 +0530792 int shift = 0;
Jaehoon Chung8788e062012-12-27 22:30:32 +0000793
794 sel = readl(&clk->src_fsys);
795 sel = (sel >> (dev_index << 2)) & 0xf;
796
797 if (sel == 0x6)
798 sclk = get_pll_clk(MPLL);
799 else if (sel == 0x7)
800 sclk = get_pll_clk(EPLL);
801 else if (sel == 0x8)
802 sclk = get_pll_clk(VPLL);
803 else
804 return 0;
805
806 switch (dev_index) {
807 case 0:
808 case 1:
809 ratio = readl(&clk->div_fsys1);
810 pre_ratio = readl(&clk->div_fsys1);
811 break;
812 case 2:
813 case 3:
814 ratio = readl(&clk->div_fsys2);
815 pre_ratio = readl(&clk->div_fsys2);
816 break;
817 default:
818 return 0;
819 }
820
821 if (dev_index == 1 || dev_index == 3)
822 shift = 16;
823
824 ratio = (ratio >> shift) & 0xf;
825 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
826 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
827
828 return uclk;
829}
830
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530831static unsigned long exynos5420_get_mmc_clk(int dev_index)
832{
833 struct exynos5420_clock *clk =
834 (struct exynos5420_clock *)samsung_get_base_clock();
835 unsigned long uclk, sclk;
836 unsigned int sel, ratio;
837
838 /*
839 * CLK_SRC_FSYS
840 * MMC0_SEL [10:8]
841 * MMC1_SEL [14:12]
842 * MMC2_SEL [18:16]
843 * generalised calculation as follows
844 * sel = (sel >> ((dev_index * 4) + 8)) & mask
845 */
846 sel = readl(&clk->src_fsys);
847 sel = (sel >> ((dev_index * 4) + 8)) & 0x7;
848
849 if (sel == 0x3)
850 sclk = get_pll_clk(MPLL);
Joonyoung Shim615e1482014-12-22 19:46:30 +0900851 else if (sel == 0x4)
852 sclk = get_pll_clk(SPLL);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530853 else if (sel == 0x6)
854 sclk = get_pll_clk(EPLL);
855 else
856 return 0;
857
858 /*
859 * CLK_DIV_FSYS1
860 * MMC0_RATIO [9:0]
861 * MMC1_RATIO [19:10]
862 * MMC2_RATIO [29:20]
863 * generalised calculation as follows
864 * ratio = (ratio >> (dev_index * 10)) & mask
865 */
866 ratio = readl(&clk->div_fsys1);
867 ratio = (ratio >> (dev_index * 10)) & 0x3ff;
868
869 uclk = (sclk / (ratio + 1));
870
871 return uclk;
872}
873
Chander Kashyap4131a772011-12-06 23:34:12 +0000874/* exynos4: set the mmc clock */
875static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
Jaehoon Chung9a772212011-05-17 21:19:17 +0000876{
Chander Kashyap4131a772011-12-06 23:34:12 +0000877 struct exynos4_clock *clk =
878 (struct exynos4_clock *)samsung_get_base_clock();
Jaehoon Chungd2c83242014-05-16 13:59:50 +0900879 unsigned int addr, clear_bit, set_bit;
Jaehoon Chung9a772212011-05-17 21:19:17 +0000880
881 /*
882 * CLK_DIV_FSYS1
883 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
884 * CLK_DIV_FSYS2
885 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
Jaehoon Chung29fe8c52012-12-27 22:30:33 +0000886 * CLK_DIV_FSYS3
Jaehoon Chungd2c83242014-05-16 13:59:50 +0900887 * MMC4_RATIO [3:0]
Jaehoon Chung9a772212011-05-17 21:19:17 +0000888 */
889 if (dev_index < 2) {
890 addr = (unsigned int)&clk->div_fsys1;
Jaehoon Chungd2c83242014-05-16 13:59:50 +0900891 clear_bit = MASK_PRE_RATIO(dev_index);
892 set_bit = SET_PRE_RATIO(dev_index, div);
893 } else if (dev_index == 4) {
Jaehoon Chung29fe8c52012-12-27 22:30:33 +0000894 addr = (unsigned int)&clk->div_fsys3;
895 dev_index -= 4;
Jaehoon Chungd2c83242014-05-16 13:59:50 +0900896 /* MMC4 is controlled with the MMC4_RATIO value */
897 clear_bit = MASK_RATIO(dev_index);
898 set_bit = SET_RATIO(dev_index, div);
Jaehoon Chung9a772212011-05-17 21:19:17 +0000899 } else {
900 addr = (unsigned int)&clk->div_fsys2;
901 dev_index -= 2;
Jaehoon Chungd2c83242014-05-16 13:59:50 +0900902 clear_bit = MASK_PRE_RATIO(dev_index);
903 set_bit = SET_PRE_RATIO(dev_index, div);
Jaehoon Chung9a772212011-05-17 21:19:17 +0000904 }
905
Jaehoon Chungd2c83242014-05-16 13:59:50 +0900906 clrsetbits_le32(addr, clear_bit, set_bit);
Jaehoon Chung9a772212011-05-17 21:19:17 +0000907}
908
Chander Kashyap34076a02012-02-05 23:01:46 +0000909/* exynos5: set the mmc clock */
910static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
911{
912 struct exynos5_clock *clk =
913 (struct exynos5_clock *)samsung_get_base_clock();
914 unsigned int addr;
Chander Kashyap34076a02012-02-05 23:01:46 +0000915
916 /*
917 * CLK_DIV_FSYS1
918 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
919 * CLK_DIV_FSYS2
920 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
921 */
922 if (dev_index < 2) {
923 addr = (unsigned int)&clk->div_fsys1;
924 } else {
925 addr = (unsigned int)&clk->div_fsys2;
926 dev_index -= 2;
927 }
928
Inha Song4e558532014-02-06 14:20:12 +0900929 clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8),
930 (div & 0xff) << ((dev_index << 4) + 8));
Chander Kashyap34076a02012-02-05 23:01:46 +0000931}
932
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530933/* exynos5: set the mmc clock */
934static void exynos5420_set_mmc_clk(int dev_index, unsigned int div)
935{
936 struct exynos5420_clock *clk =
937 (struct exynos5420_clock *)samsung_get_base_clock();
938 unsigned int addr;
Inha Song4e558532014-02-06 14:20:12 +0900939 unsigned int shift;
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530940
941 /*
942 * CLK_DIV_FSYS1
943 * MMC0_RATIO [9:0]
944 * MMC1_RATIO [19:10]
945 * MMC2_RATIO [29:20]
946 */
947 addr = (unsigned int)&clk->div_fsys1;
948 shift = dev_index * 10;
949
Inha Song4e558532014-02-06 14:20:12 +0900950 clrsetbits_le32(addr, 0x3ff << shift, (div & 0x3ff) << shift);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530951}
952
Donghwa Lee77ba1912012-04-05 19:36:12 +0000953/* get_lcd_clk: return lcd clock frequency */
954static unsigned long exynos4_get_lcd_clk(void)
955{
956 struct exynos4_clock *clk =
957 (struct exynos4_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_lcd0);
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_lcd0);
988 ratio = ratio & 0xf;
989
990 pclk = sclk / (ratio + 1);
991
992 return pclk;
993}
994
Donghwa Lee3c9d4532012-07-02 01:15:49 +0000995/* get_lcd_clk: return lcd clock frequency */
996static unsigned long exynos5_get_lcd_clk(void)
997{
998 struct exynos5_clock *clk =
999 (struct exynos5_clock *)samsung_get_base_clock();
1000 unsigned long pclk, sclk;
1001 unsigned int sel;
1002 unsigned int ratio;
1003
1004 /*
1005 * CLK_SRC_LCD0
1006 * FIMD0_SEL [3:0]
1007 */
1008 sel = readl(&clk->src_disp1_0);
1009 sel = sel & 0xf;
1010
1011 /*
1012 * 0x6: SCLK_MPLL
1013 * 0x7: SCLK_EPLL
1014 * 0x8: SCLK_VPLL
1015 */
1016 if (sel == 0x6)
1017 sclk = get_pll_clk(MPLL);
1018 else if (sel == 0x7)
1019 sclk = get_pll_clk(EPLL);
1020 else if (sel == 0x8)
1021 sclk = get_pll_clk(VPLL);
1022 else
1023 return 0;
1024
1025 /*
1026 * CLK_DIV_LCD0
1027 * FIMD0_RATIO [3:0]
1028 */
1029 ratio = readl(&clk->div_disp1_0);
1030 ratio = ratio & 0xf;
1031
1032 pclk = sclk / (ratio + 1);
1033
1034 return pclk;
1035}
1036
Ajay Kumar914af872014-09-05 16:53:32 +05301037static unsigned long exynos5420_get_lcd_clk(void)
1038{
1039 struct exynos5420_clock *clk =
1040 (struct exynos5420_clock *)samsung_get_base_clock();
1041 unsigned long pclk, sclk;
1042 unsigned int sel;
1043 unsigned int ratio;
1044
1045 /*
1046 * CLK_SRC_DISP10
1047 * FIMD1_SEL [4]
1048 * 0: SCLK_RPLL
1049 * 1: SCLK_SPLL
1050 */
1051 sel = readl(&clk->src_disp10);
1052 sel &= (1 << 4);
1053
1054 if (sel)
1055 sclk = get_pll_clk(SPLL);
1056 else
1057 sclk = get_pll_clk(RPLL);
1058
1059 /*
1060 * CLK_DIV_DISP10
1061 * FIMD1_RATIO [3:0]
1062 */
1063 ratio = readl(&clk->div_disp10);
1064 ratio = ratio & 0xf;
1065
1066 pclk = sclk / (ratio + 1);
1067
1068 return pclk;
1069}
1070
Donghwa Lee77ba1912012-04-05 19:36:12 +00001071void exynos4_set_lcd_clk(void)
1072{
1073 struct exynos4_clock *clk =
1074 (struct exynos4_clock *)samsung_get_base_clock();
Donghwa Lee77ba1912012-04-05 19:36:12 +00001075
1076 /*
1077 * CLK_GATE_BLOCK
1078 * CLK_CAM [0]
1079 * CLK_TV [1]
1080 * CLK_MFC [2]
1081 * CLK_G3D [3]
1082 * CLK_LCD0 [4]
1083 * CLK_LCD1 [5]
1084 * CLK_GPS [7]
1085 */
Inha Song4e558532014-02-06 14:20:12 +09001086 setbits_le32(&clk->gate_block, 1 << 4);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001087
1088 /*
1089 * CLK_SRC_LCD0
1090 * FIMD0_SEL [3:0]
1091 * MDNIE0_SEL [7:4]
1092 * MDNIE_PWM0_SEL [8:11]
1093 * MIPI0_SEL [12:15]
1094 * set lcd0 src clock 0x6: SCLK_MPLL
1095 */
Inha Song4e558532014-02-06 14:20:12 +09001096 clrsetbits_le32(&clk->src_lcd0, 0xf, 0x6);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001097
1098 /*
1099 * CLK_GATE_IP_LCD0
1100 * CLK_FIMD0 [0]
1101 * CLK_MIE0 [1]
1102 * CLK_MDNIE0 [2]
1103 * CLK_DSIM0 [3]
1104 * CLK_SMMUFIMD0 [4]
1105 * CLK_PPMULCD0 [5]
1106 * Gating all clocks for FIMD0
1107 */
Inha Song4e558532014-02-06 14:20:12 +09001108 setbits_le32(&clk->gate_ip_lcd0, 1 << 0);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001109
1110 /*
1111 * CLK_DIV_LCD0
1112 * FIMD0_RATIO [3:0]
1113 * MDNIE0_RATIO [7:4]
1114 * MDNIE_PWM0_RATIO [11:8]
1115 * MDNIE_PWM_PRE_RATIO [15:12]
1116 * MIPI0_RATIO [19:16]
1117 * MIPI0_PRE_RATIO [23:20]
1118 * set fimd ratio
1119 */
Inha Song4e558532014-02-06 14:20:12 +09001120 clrsetbits_le32(&clk->div_lcd0, 0xf, 0x1);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001121}
1122
Donghwa Lee3c9d4532012-07-02 01:15:49 +00001123void exynos5_set_lcd_clk(void)
1124{
1125 struct exynos5_clock *clk =
1126 (struct exynos5_clock *)samsung_get_base_clock();
Donghwa Lee3c9d4532012-07-02 01:15:49 +00001127
1128 /*
1129 * CLK_GATE_BLOCK
1130 * CLK_CAM [0]
1131 * CLK_TV [1]
1132 * CLK_MFC [2]
1133 * CLK_G3D [3]
1134 * CLK_LCD0 [4]
1135 * CLK_LCD1 [5]
1136 * CLK_GPS [7]
1137 */
Inha Song4e558532014-02-06 14:20:12 +09001138 setbits_le32(&clk->gate_block, 1 << 4);
Donghwa Lee3c9d4532012-07-02 01:15:49 +00001139
1140 /*
1141 * CLK_SRC_LCD0
1142 * FIMD0_SEL [3:0]
1143 * MDNIE0_SEL [7:4]
1144 * MDNIE_PWM0_SEL [8:11]
1145 * MIPI0_SEL [12:15]
1146 * set lcd0 src clock 0x6: SCLK_MPLL
1147 */
Inha Song4e558532014-02-06 14:20:12 +09001148 clrsetbits_le32(&clk->src_disp1_0, 0xf, 0x6);
Donghwa Lee3c9d4532012-07-02 01:15:49 +00001149
1150 /*
1151 * CLK_GATE_IP_LCD0
1152 * CLK_FIMD0 [0]
1153 * CLK_MIE0 [1]
1154 * CLK_MDNIE0 [2]
1155 * CLK_DSIM0 [3]
1156 * CLK_SMMUFIMD0 [4]
1157 * CLK_PPMULCD0 [5]
1158 * Gating all clocks for FIMD0
1159 */
Inha Song4e558532014-02-06 14:20:12 +09001160 setbits_le32(&clk->gate_ip_disp1, 1 << 0);
Donghwa Lee3c9d4532012-07-02 01:15:49 +00001161
1162 /*
1163 * CLK_DIV_LCD0
1164 * FIMD0_RATIO [3:0]
1165 * MDNIE0_RATIO [7:4]
1166 * MDNIE_PWM0_RATIO [11:8]
1167 * MDNIE_PWM_PRE_RATIO [15:12]
1168 * MIPI0_RATIO [19:16]
1169 * MIPI0_PRE_RATIO [23:20]
1170 * set fimd ratio
1171 */
Inha Song4e558532014-02-06 14:20:12 +09001172 clrsetbits_le32(&clk->div_disp1_0, 0xf, 0x0);
Donghwa Lee3c9d4532012-07-02 01:15:49 +00001173}
1174
Ajay Kumar914af872014-09-05 16:53:32 +05301175void exynos5420_set_lcd_clk(void)
1176{
1177 struct exynos5420_clock *clk =
1178 (struct exynos5420_clock *)samsung_get_base_clock();
1179 unsigned int cfg;
1180
1181 /*
1182 * CLK_SRC_DISP10
1183 * FIMD1_SEL [4]
1184 * 0: SCLK_RPLL
1185 * 1: SCLK_SPLL
1186 */
1187 cfg = readl(&clk->src_disp10);
1188 cfg &= ~(0x1 << 4);
1189 cfg |= (0 << 4);
1190 writel(cfg, &clk->src_disp10);
1191
1192 /*
1193 * CLK_DIV_DISP10
1194 * FIMD1_RATIO [3:0]
1195 */
1196 cfg = readl(&clk->div_disp10);
1197 cfg &= ~(0xf << 0);
1198 cfg |= (0 << 0);
1199 writel(cfg, &clk->div_disp10);
1200}
1201
Donghwa Lee77ba1912012-04-05 19:36:12 +00001202void exynos4_set_mipi_clk(void)
1203{
1204 struct exynos4_clock *clk =
1205 (struct exynos4_clock *)samsung_get_base_clock();
Donghwa Lee77ba1912012-04-05 19:36:12 +00001206
1207 /*
1208 * CLK_SRC_LCD0
1209 * FIMD0_SEL [3:0]
1210 * MDNIE0_SEL [7:4]
1211 * MDNIE_PWM0_SEL [8:11]
1212 * MIPI0_SEL [12:15]
1213 * set mipi0 src clock 0x6: SCLK_MPLL
1214 */
Inha Song4e558532014-02-06 14:20:12 +09001215 clrsetbits_le32(&clk->src_lcd0, 0xf << 12, 0x6 << 12);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001216
1217 /*
1218 * CLK_SRC_MASK_LCD0
1219 * FIMD0_MASK [0]
1220 * MDNIE0_MASK [4]
1221 * MDNIE_PWM0_MASK [8]
1222 * MIPI0_MASK [12]
1223 * set src mask mipi0 0x1: Unmask
1224 */
Inha Song4e558532014-02-06 14:20:12 +09001225 setbits_le32(&clk->src_mask_lcd0, 0x1 << 12);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001226
1227 /*
1228 * CLK_GATE_IP_LCD0
1229 * CLK_FIMD0 [0]
1230 * CLK_MIE0 [1]
1231 * CLK_MDNIE0 [2]
1232 * CLK_DSIM0 [3]
1233 * CLK_SMMUFIMD0 [4]
1234 * CLK_PPMULCD0 [5]
1235 * Gating all clocks for MIPI0
1236 */
Inha Song4e558532014-02-06 14:20:12 +09001237 setbits_le32(&clk->gate_ip_lcd0, 1 << 3);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001238
1239 /*
1240 * CLK_DIV_LCD0
1241 * FIMD0_RATIO [3:0]
1242 * MDNIE0_RATIO [7:4]
1243 * MDNIE_PWM0_RATIO [11:8]
1244 * MDNIE_PWM_PRE_RATIO [15:12]
1245 * MIPI0_RATIO [19:16]
1246 * MIPI0_PRE_RATIO [23:20]
1247 * set mipi ratio
1248 */
Inha Song4e558532014-02-06 14:20:12 +09001249 clrsetbits_le32(&clk->div_lcd0, 0xf << 16, 0x1 << 16);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001250}
1251
Rajeshwari Shinde1c9412a2012-07-23 21:23:48 +00001252/*
1253 * I2C
1254 *
1255 * exynos5: obtaining the I2C clock
1256 */
1257static unsigned long exynos5_get_i2c_clk(void)
1258{
1259 struct exynos5_clock *clk =
1260 (struct exynos5_clock *)samsung_get_base_clock();
1261 unsigned long aclk_66, aclk_66_pre, sclk;
1262 unsigned int ratio;
1263
1264 sclk = get_pll_clk(MPLL);
1265
1266 ratio = (readl(&clk->div_top1)) >> 24;
1267 ratio &= 0x7;
1268 aclk_66_pre = sclk / (ratio + 1);
1269 ratio = readl(&clk->div_top0);
1270 ratio &= 0x7;
1271 aclk_66 = aclk_66_pre / (ratio + 1);
1272 return aclk_66;
1273}
1274
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001275int exynos5_set_epll_clk(unsigned long rate)
1276{
1277 unsigned int epll_con, epll_con_k;
1278 unsigned int i;
1279 unsigned int lockcnt;
1280 unsigned int start;
1281 struct exynos5_clock *clk =
1282 (struct exynos5_clock *)samsung_get_base_clock();
1283
1284 epll_con = readl(&clk->epll_con0);
1285 epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
1286 EPLL_CON0_LOCK_DET_EN_SHIFT) |
1287 EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
1288 EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
1289 EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
1290
1291 for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) {
1292 if (exynos5_epll_div[i].freq_out == rate)
1293 break;
1294 }
1295
1296 if (i == ARRAY_SIZE(exynos5_epll_div))
1297 return -1;
1298
1299 epll_con_k = exynos5_epll_div[i].k_dsm << 0;
1300 epll_con |= exynos5_epll_div[i].en_lock_det <<
1301 EPLL_CON0_LOCK_DET_EN_SHIFT;
1302 epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
1303 epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
1304 epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
1305
1306 /*
1307 * Required period ( in cycles) to genarate a stable clock output.
1308 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
1309 * frequency input (as per spec)
1310 */
1311 lockcnt = 3000 * exynos5_epll_div[i].p_div;
1312
1313 writel(lockcnt, &clk->epll_lock);
1314 writel(epll_con, &clk->epll_con0);
1315 writel(epll_con_k, &clk->epll_con1);
1316
1317 start = get_timer(0);
1318
1319 while (!(readl(&clk->epll_con0) &
1320 (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
1321 if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
1322 debug("%s: Timeout waiting for EPLL lock\n", __func__);
1323 return -1;
1324 }
1325 }
1326 return 0;
1327}
1328
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301329int exynos5_set_i2s_clk_source(unsigned int i2s_id)
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001330{
1331 struct exynos5_clock *clk =
1332 (struct exynos5_clock *)samsung_get_base_clock();
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301333 unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass();
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001334
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301335 if (i2s_id == 0) {
1336 setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL);
1337 clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK,
1338 (CLK_SRC_SCLK_EPLL));
1339 setbits_le32(audio_ass, AUDIO_CLKMUX_ASS);
1340 } else if (i2s_id == 1) {
1341 clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
1342 (CLK_SRC_SCLK_EPLL));
1343 } else {
1344 return -1;
1345 }
1346 return 0;
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001347}
1348
1349int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301350 unsigned int dst_frq,
1351 unsigned int i2s_id)
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001352{
1353 struct exynos5_clock *clk =
1354 (struct exynos5_clock *)samsung_get_base_clock();
1355 unsigned int div;
1356
1357 if ((dst_frq == 0) || (src_frq == 0)) {
1358 debug("%s: Invalid requency input for prescaler\n", __func__);
1359 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1360 return -1;
1361 }
1362
1363 div = (src_frq / dst_frq);
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301364 if (i2s_id == 0) {
1365 if (div > AUDIO_0_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_mau, AUDIO_0_RATIO_MASK,
1372 (div & AUDIO_0_RATIO_MASK));
1373 } else if(i2s_id == 1) {
1374 if (div > AUDIO_1_RATIO_MASK) {
1375 debug("%s: Frequency ratio is out of range\n",
1376 __func__);
1377 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1378 return -1;
1379 }
1380 clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
1381 (div & AUDIO_1_RATIO_MASK));
1382 } else {
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001383 return -1;
1384 }
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001385 return 0;
1386}
1387
Hatim RVe6365b62012-11-02 01:15:34 +00001388/**
1389 * Linearly searches for the most accurate main and fine stage clock scalars
1390 * (divisors) for a specified target frequency and scalar bit sizes by checking
1391 * all multiples of main_scalar_bits values. Will always return scalars up to or
1392 * slower than target.
1393 *
1394 * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
1395 * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
1396 * @param input_freq Clock frequency to be scaled in Hz
1397 * @param target_freq Desired clock frequency in Hz
1398 * @param best_fine_scalar Pointer to store the fine stage divisor
1399 *
1400 * @return best_main_scalar Main scalar for desired frequency or -1 if none
1401 * found
1402 */
1403static int clock_calc_best_scalar(unsigned int main_scaler_bits,
1404 unsigned int fine_scalar_bits, unsigned int input_rate,
1405 unsigned int target_rate, unsigned int *best_fine_scalar)
1406{
1407 int i;
1408 int best_main_scalar = -1;
1409 unsigned int best_error = target_rate;
1410 const unsigned int cap = (1 << fine_scalar_bits) - 1;
1411 const unsigned int loops = 1 << main_scaler_bits;
1412
1413 debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
1414 target_rate, cap);
1415
1416 assert(best_fine_scalar != NULL);
1417 assert(main_scaler_bits <= fine_scalar_bits);
1418
1419 *best_fine_scalar = 1;
1420
1421 if (input_rate == 0 || target_rate == 0)
1422 return -1;
1423
1424 if (target_rate >= input_rate)
1425 return 1;
1426
1427 for (i = 1; i <= loops; i++) {
Masahiro Yamadadb204642014-11-07 03:03:31 +09001428 const unsigned int effective_div =
1429 max(min(input_rate / i / target_rate, cap), 1U);
Hatim RVe6365b62012-11-02 01:15:34 +00001430 const unsigned int effective_rate = input_rate / i /
1431 effective_div;
1432 const int error = target_rate - effective_rate;
1433
1434 debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
1435 effective_rate, error);
1436
1437 if (error >= 0 && error <= best_error) {
1438 best_error = error;
1439 best_main_scalar = i;
1440 *best_fine_scalar = effective_div;
1441 }
1442 }
1443
1444 return best_main_scalar;
1445}
1446
1447static int exynos5_set_spi_clk(enum periph_id periph_id,
1448 unsigned int rate)
1449{
1450 struct exynos5_clock *clk =
1451 (struct exynos5_clock *)samsung_get_base_clock();
1452 int main;
1453 unsigned int fine;
1454 unsigned shift, pre_shift;
1455 unsigned mask = 0xff;
1456 u32 *reg;
1457
1458 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1459 if (main < 0) {
1460 debug("%s: Cannot set clock rate for periph %d",
1461 __func__, periph_id);
1462 return -1;
1463 }
1464 main = main - 1;
1465 fine = fine - 1;
1466
1467 switch (periph_id) {
1468 case PERIPH_ID_SPI0:
1469 reg = &clk->div_peric1;
1470 shift = 0;
1471 pre_shift = 8;
1472 break;
1473 case PERIPH_ID_SPI1:
1474 reg = &clk->div_peric1;
1475 shift = 16;
1476 pre_shift = 24;
1477 break;
1478 case PERIPH_ID_SPI2:
1479 reg = &clk->div_peric2;
1480 shift = 0;
1481 pre_shift = 8;
1482 break;
1483 case PERIPH_ID_SPI3:
1484 reg = &clk->sclk_div_isp;
1485 shift = 0;
1486 pre_shift = 4;
1487 break;
1488 case PERIPH_ID_SPI4:
1489 reg = &clk->sclk_div_isp;
1490 shift = 12;
1491 pre_shift = 16;
1492 break;
1493 default:
1494 debug("%s: Unsupported peripheral ID %d\n", __func__,
1495 periph_id);
1496 return -1;
1497 }
1498 clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
1499 clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
1500
1501 return 0;
1502}
1503
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301504static int exynos5420_set_spi_clk(enum periph_id periph_id,
1505 unsigned int rate)
1506{
1507 struct exynos5420_clock *clk =
1508 (struct exynos5420_clock *)samsung_get_base_clock();
1509 int main;
1510 unsigned int fine;
1511 unsigned shift, pre_shift;
1512 unsigned div_mask = 0xf, pre_div_mask = 0xff;
1513 u32 *reg;
1514 u32 *pre_reg;
1515
1516 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1517 if (main < 0) {
1518 debug("%s: Cannot set clock rate for periph %d",
1519 __func__, periph_id);
1520 return -1;
1521 }
1522 main = main - 1;
1523 fine = fine - 1;
1524
1525 switch (periph_id) {
1526 case PERIPH_ID_SPI0:
1527 reg = &clk->div_peric1;
1528 shift = 20;
1529 pre_reg = &clk->div_peric4;
1530 pre_shift = 8;
1531 break;
1532 case PERIPH_ID_SPI1:
1533 reg = &clk->div_peric1;
1534 shift = 24;
1535 pre_reg = &clk->div_peric4;
1536 pre_shift = 16;
1537 break;
1538 case PERIPH_ID_SPI2:
1539 reg = &clk->div_peric1;
1540 shift = 28;
1541 pre_reg = &clk->div_peric4;
1542 pre_shift = 24;
1543 break;
1544 case PERIPH_ID_SPI3:
1545 reg = &clk->div_isp1;
1546 shift = 16;
1547 pre_reg = &clk->div_isp1;
1548 pre_shift = 0;
1549 break;
1550 case PERIPH_ID_SPI4:
1551 reg = &clk->div_isp1;
1552 shift = 20;
1553 pre_reg = &clk->div_isp1;
1554 pre_shift = 8;
1555 break;
1556 default:
1557 debug("%s: Unsupported peripheral ID %d\n", __func__,
1558 periph_id);
1559 return -1;
1560 }
1561
1562 clrsetbits_le32(reg, div_mask << shift, (main & div_mask) << shift);
1563 clrsetbits_le32(pre_reg, pre_div_mask << pre_shift,
1564 (fine & pre_div_mask) << pre_shift);
1565
1566 return 0;
1567}
1568
Piotr Wilczek01d589f2012-11-20 02:19:02 +00001569static unsigned long exynos4_get_i2c_clk(void)
1570{
1571 struct exynos4_clock *clk =
1572 (struct exynos4_clock *)samsung_get_base_clock();
1573 unsigned long sclk, aclk_100;
1574 unsigned int ratio;
1575
1576 sclk = get_pll_clk(APLL);
1577
1578 ratio = (readl(&clk->div_top)) >> 4;
1579 ratio &= 0xf;
1580 aclk_100 = sclk / (ratio + 1);
1581 return aclk_100;
Minkyu Kangb1b24682011-01-24 15:22:23 +09001582}
1583
1584unsigned long get_pll_clk(int pllreg)
1585{
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301586 if (cpu_is_exynos5()) {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301587 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301588 return exynos5420_get_pll_clk(pllreg);
Chander Kashyap34076a02012-02-05 23:01:46 +00001589 return exynos5_get_pll_clk(pllreg);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301590 } else {
Chander Kashyap400ab162012-10-07 01:43:17 +00001591 if (proid_is_exynos4412())
1592 return exynos4x12_get_pll_clk(pllreg);
Chander Kashyap34076a02012-02-05 23:01:46 +00001593 return exynos4_get_pll_clk(pllreg);
Chander Kashyap400ab162012-10-07 01:43:17 +00001594 }
Minkyu Kangb1b24682011-01-24 15:22:23 +09001595}
1596
1597unsigned long get_arm_clk(void)
1598{
Chander Kashyap34076a02012-02-05 23:01:46 +00001599 if (cpu_is_exynos5())
1600 return exynos5_get_arm_clk();
Chander Kashyap400ab162012-10-07 01:43:17 +00001601 else {
1602 if (proid_is_exynos4412())
1603 return exynos4x12_get_arm_clk();
Chander Kashyap34076a02012-02-05 23:01:46 +00001604 return exynos4_get_arm_clk();
Chander Kashyap400ab162012-10-07 01:43:17 +00001605 }
Minkyu Kangb1b24682011-01-24 15:22:23 +09001606}
1607
Rajeshwari Shinde1c9412a2012-07-23 21:23:48 +00001608unsigned long get_i2c_clk(void)
1609{
1610 if (cpu_is_exynos5()) {
1611 return exynos5_get_i2c_clk();
Piotr Wilczek01d589f2012-11-20 02:19:02 +00001612 } else if (cpu_is_exynos4()) {
1613 return exynos4_get_i2c_clk();
Rajeshwari Shinde1c9412a2012-07-23 21:23:48 +00001614 } else {
1615 debug("I2C clock is not set for this CPU\n");
1616 return 0;
1617 }
1618}
1619
Minkyu Kangb1b24682011-01-24 15:22:23 +09001620unsigned long get_pwm_clk(void)
1621{
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301622 if (cpu_is_exynos5()) {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301623 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301624 return exynos5420_get_pwm_clk();
Padmavathi Vennabb714162013-03-28 04:32:23 +00001625 return clock_get_periph_rate(PERIPH_ID_PWM0);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301626 } else {
Chander Kashyap400ab162012-10-07 01:43:17 +00001627 if (proid_is_exynos4412())
1628 return exynos4x12_get_pwm_clk();
Chander Kashyap34076a02012-02-05 23:01:46 +00001629 return exynos4_get_pwm_clk();
Chander Kashyap400ab162012-10-07 01:43:17 +00001630 }
Minkyu Kangb1b24682011-01-24 15:22:23 +09001631}
1632
1633unsigned long get_uart_clk(int dev_index)
1634{
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301635 if (cpu_is_exynos5()) {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301636 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301637 return exynos5420_get_uart_clk(dev_index);
Chander Kashyap34076a02012-02-05 23:01:46 +00001638 return exynos5_get_uart_clk(dev_index);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301639 } else {
Chander Kashyap400ab162012-10-07 01:43:17 +00001640 if (proid_is_exynos4412())
1641 return exynos4x12_get_uart_clk(dev_index);
Chander Kashyap34076a02012-02-05 23:01:46 +00001642 return exynos4_get_uart_clk(dev_index);
Chander Kashyap400ab162012-10-07 01:43:17 +00001643 }
Minkyu Kangb1b24682011-01-24 15:22:23 +09001644}
Jaehoon Chung9a772212011-05-17 21:19:17 +00001645
Jaehoon Chung8788e062012-12-27 22:30:32 +00001646unsigned long get_mmc_clk(int dev_index)
1647{
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301648 if (cpu_is_exynos5()) {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301649 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301650 return exynos5420_get_mmc_clk(dev_index);
Jaehoon Chung8788e062012-12-27 22:30:32 +00001651 return exynos5_get_mmc_clk(dev_index);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301652 } else {
Jaehoon Chung8788e062012-12-27 22:30:32 +00001653 return exynos4_get_mmc_clk(dev_index);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301654 }
Jaehoon Chung8788e062012-12-27 22:30:32 +00001655}
1656
Jaehoon Chung9a772212011-05-17 21:19:17 +00001657void set_mmc_clk(int dev_index, unsigned int div)
1658{
Jaehoon Chung15cd6b52015-01-08 16:50:21 +09001659 /* If want to set correct value, it needs to substract one from div.*/
1660 if (div > 0)
1661 div -= 1;
1662
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301663 if (cpu_is_exynos5()) {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301664 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301665 exynos5420_set_mmc_clk(dev_index, div);
1666 else
1667 exynos5_set_mmc_clk(dev_index, div);
1668 } else {
Beomho Seo99660cc2014-05-16 13:59:47 +09001669 exynos4_set_mmc_clk(dev_index, div);
Chander Kashyap400ab162012-10-07 01:43:17 +00001670 }
Jaehoon Chung9a772212011-05-17 21:19:17 +00001671}
Donghwa Lee77ba1912012-04-05 19:36:12 +00001672
1673unsigned long get_lcd_clk(void)
1674{
1675 if (cpu_is_exynos4())
1676 return exynos4_get_lcd_clk();
Ajay Kumar914af872014-09-05 16:53:32 +05301677 else {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301678 if (proid_is_exynos5420() || proid_is_exynos5800())
Ajay Kumar914af872014-09-05 16:53:32 +05301679 return exynos5420_get_lcd_clk();
1680 else
1681 return exynos5_get_lcd_clk();
1682 }
Donghwa Lee77ba1912012-04-05 19:36:12 +00001683}
1684
1685void set_lcd_clk(void)
1686{
1687 if (cpu_is_exynos4())
1688 exynos4_set_lcd_clk();
Ajay Kumar914af872014-09-05 16:53:32 +05301689 else {
1690 if (proid_is_exynos5250())
1691 exynos5_set_lcd_clk();
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301692 else if (proid_is_exynos5420() || proid_is_exynos5800())
Ajay Kumar914af872014-09-05 16:53:32 +05301693 exynos5420_set_lcd_clk();
1694 }
Donghwa Lee77ba1912012-04-05 19:36:12 +00001695}
1696
1697void set_mipi_clk(void)
1698{
1699 if (cpu_is_exynos4())
1700 exynos4_set_mipi_clk();
1701}
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001702
Hatim RVe6365b62012-11-02 01:15:34 +00001703int set_spi_clk(int periph_id, unsigned int rate)
1704{
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301705 if (cpu_is_exynos5()) {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301706 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301707 return exynos5420_set_spi_clk(periph_id, rate);
Hatim RVe6365b62012-11-02 01:15:34 +00001708 return exynos5_set_spi_clk(periph_id, rate);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301709 } else {
Hatim RVe6365b62012-11-02 01:15:34 +00001710 return 0;
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301711 }
Hatim RVe6365b62012-11-02 01:15:34 +00001712}
1713
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301714int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
1715 unsigned int i2s_id)
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001716{
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001717 if (cpu_is_exynos5())
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301718 return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id);
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001719 else
1720 return 0;
1721}
1722
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301723int set_i2s_clk_source(unsigned int i2s_id)
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001724{
1725 if (cpu_is_exynos5())
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301726 return exynos5_set_i2s_clk_source(i2s_id);
1727 else
1728 return 0;
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001729}
1730
1731int set_epll_clk(unsigned long rate)
1732{
1733 if (cpu_is_exynos5())
1734 return exynos5_set_epll_clk(rate);
1735 else
1736 return 0;
1737}