blob: 8fab135bebf4ef6900677847b60a8e1a1520254c [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);
851 else if (sel == 0x6)
852 sclk = get_pll_clk(EPLL);
853 else
854 return 0;
855
856 /*
857 * CLK_DIV_FSYS1
858 * MMC0_RATIO [9:0]
859 * MMC1_RATIO [19:10]
860 * MMC2_RATIO [29:20]
861 * generalised calculation as follows
862 * ratio = (ratio >> (dev_index * 10)) & mask
863 */
864 ratio = readl(&clk->div_fsys1);
865 ratio = (ratio >> (dev_index * 10)) & 0x3ff;
866
867 uclk = (sclk / (ratio + 1));
868
869 return uclk;
870}
871
Chander Kashyap4131a772011-12-06 23:34:12 +0000872/* exynos4: set the mmc clock */
873static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
Jaehoon Chung9a772212011-05-17 21:19:17 +0000874{
Chander Kashyap4131a772011-12-06 23:34:12 +0000875 struct exynos4_clock *clk =
876 (struct exynos4_clock *)samsung_get_base_clock();
Jaehoon Chungd2c83242014-05-16 13:59:50 +0900877 unsigned int addr, clear_bit, set_bit;
Jaehoon Chung9a772212011-05-17 21:19:17 +0000878
879 /*
880 * CLK_DIV_FSYS1
881 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
882 * CLK_DIV_FSYS2
883 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
Jaehoon Chung29fe8c52012-12-27 22:30:33 +0000884 * CLK_DIV_FSYS3
Jaehoon Chungd2c83242014-05-16 13:59:50 +0900885 * MMC4_RATIO [3:0]
Jaehoon Chung9a772212011-05-17 21:19:17 +0000886 */
887 if (dev_index < 2) {
888 addr = (unsigned int)&clk->div_fsys1;
Jaehoon Chungd2c83242014-05-16 13:59:50 +0900889 clear_bit = MASK_PRE_RATIO(dev_index);
890 set_bit = SET_PRE_RATIO(dev_index, div);
891 } else if (dev_index == 4) {
Jaehoon Chung29fe8c52012-12-27 22:30:33 +0000892 addr = (unsigned int)&clk->div_fsys3;
893 dev_index -= 4;
Jaehoon Chungd2c83242014-05-16 13:59:50 +0900894 /* MMC4 is controlled with the MMC4_RATIO value */
895 clear_bit = MASK_RATIO(dev_index);
896 set_bit = SET_RATIO(dev_index, div);
Jaehoon Chung9a772212011-05-17 21:19:17 +0000897 } else {
898 addr = (unsigned int)&clk->div_fsys2;
899 dev_index -= 2;
Jaehoon Chungd2c83242014-05-16 13:59:50 +0900900 clear_bit = MASK_PRE_RATIO(dev_index);
901 set_bit = SET_PRE_RATIO(dev_index, div);
Jaehoon Chung9a772212011-05-17 21:19:17 +0000902 }
903
Jaehoon Chungd2c83242014-05-16 13:59:50 +0900904 clrsetbits_le32(addr, clear_bit, set_bit);
Jaehoon Chung9a772212011-05-17 21:19:17 +0000905}
906
Chander Kashyap34076a02012-02-05 23:01:46 +0000907/* exynos5: set the mmc clock */
908static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
909{
910 struct exynos5_clock *clk =
911 (struct exynos5_clock *)samsung_get_base_clock();
912 unsigned int addr;
Chander Kashyap34076a02012-02-05 23:01:46 +0000913
914 /*
915 * CLK_DIV_FSYS1
916 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
917 * CLK_DIV_FSYS2
918 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
919 */
920 if (dev_index < 2) {
921 addr = (unsigned int)&clk->div_fsys1;
922 } else {
923 addr = (unsigned int)&clk->div_fsys2;
924 dev_index -= 2;
925 }
926
Inha Song4e558532014-02-06 14:20:12 +0900927 clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8),
928 (div & 0xff) << ((dev_index << 4) + 8));
Chander Kashyap34076a02012-02-05 23:01:46 +0000929}
930
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530931/* exynos5: set the mmc clock */
932static void exynos5420_set_mmc_clk(int dev_index, unsigned int div)
933{
934 struct exynos5420_clock *clk =
935 (struct exynos5420_clock *)samsung_get_base_clock();
936 unsigned int addr;
Inha Song4e558532014-02-06 14:20:12 +0900937 unsigned int shift;
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530938
939 /*
940 * CLK_DIV_FSYS1
941 * MMC0_RATIO [9:0]
942 * MMC1_RATIO [19:10]
943 * MMC2_RATIO [29:20]
944 */
945 addr = (unsigned int)&clk->div_fsys1;
946 shift = dev_index * 10;
947
Inha Song4e558532014-02-06 14:20:12 +0900948 clrsetbits_le32(addr, 0x3ff << shift, (div & 0x3ff) << shift);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +0530949}
950
Donghwa Lee77ba1912012-04-05 19:36:12 +0000951/* get_lcd_clk: return lcd clock frequency */
952static unsigned long exynos4_get_lcd_clk(void)
953{
954 struct exynos4_clock *clk =
955 (struct exynos4_clock *)samsung_get_base_clock();
956 unsigned long pclk, sclk;
957 unsigned int sel;
958 unsigned int ratio;
959
960 /*
961 * CLK_SRC_LCD0
962 * FIMD0_SEL [3:0]
963 */
964 sel = readl(&clk->src_lcd0);
965 sel = sel & 0xf;
966
967 /*
968 * 0x6: SCLK_MPLL
969 * 0x7: SCLK_EPLL
970 * 0x8: SCLK_VPLL
971 */
972 if (sel == 0x6)
973 sclk = get_pll_clk(MPLL);
974 else if (sel == 0x7)
975 sclk = get_pll_clk(EPLL);
976 else if (sel == 0x8)
977 sclk = get_pll_clk(VPLL);
978 else
979 return 0;
980
981 /*
982 * CLK_DIV_LCD0
983 * FIMD0_RATIO [3:0]
984 */
985 ratio = readl(&clk->div_lcd0);
986 ratio = ratio & 0xf;
987
988 pclk = sclk / (ratio + 1);
989
990 return pclk;
991}
992
Donghwa Lee3c9d4532012-07-02 01:15:49 +0000993/* get_lcd_clk: return lcd clock frequency */
994static unsigned long exynos5_get_lcd_clk(void)
995{
996 struct exynos5_clock *clk =
997 (struct exynos5_clock *)samsung_get_base_clock();
998 unsigned long pclk, sclk;
999 unsigned int sel;
1000 unsigned int ratio;
1001
1002 /*
1003 * CLK_SRC_LCD0
1004 * FIMD0_SEL [3:0]
1005 */
1006 sel = readl(&clk->src_disp1_0);
1007 sel = sel & 0xf;
1008
1009 /*
1010 * 0x6: SCLK_MPLL
1011 * 0x7: SCLK_EPLL
1012 * 0x8: SCLK_VPLL
1013 */
1014 if (sel == 0x6)
1015 sclk = get_pll_clk(MPLL);
1016 else if (sel == 0x7)
1017 sclk = get_pll_clk(EPLL);
1018 else if (sel == 0x8)
1019 sclk = get_pll_clk(VPLL);
1020 else
1021 return 0;
1022
1023 /*
1024 * CLK_DIV_LCD0
1025 * FIMD0_RATIO [3:0]
1026 */
1027 ratio = readl(&clk->div_disp1_0);
1028 ratio = ratio & 0xf;
1029
1030 pclk = sclk / (ratio + 1);
1031
1032 return pclk;
1033}
1034
Ajay Kumar914af872014-09-05 16:53:32 +05301035static unsigned long exynos5420_get_lcd_clk(void)
1036{
1037 struct exynos5420_clock *clk =
1038 (struct exynos5420_clock *)samsung_get_base_clock();
1039 unsigned long pclk, sclk;
1040 unsigned int sel;
1041 unsigned int ratio;
1042
1043 /*
1044 * CLK_SRC_DISP10
1045 * FIMD1_SEL [4]
1046 * 0: SCLK_RPLL
1047 * 1: SCLK_SPLL
1048 */
1049 sel = readl(&clk->src_disp10);
1050 sel &= (1 << 4);
1051
1052 if (sel)
1053 sclk = get_pll_clk(SPLL);
1054 else
1055 sclk = get_pll_clk(RPLL);
1056
1057 /*
1058 * CLK_DIV_DISP10
1059 * FIMD1_RATIO [3:0]
1060 */
1061 ratio = readl(&clk->div_disp10);
1062 ratio = ratio & 0xf;
1063
1064 pclk = sclk / (ratio + 1);
1065
1066 return pclk;
1067}
1068
Donghwa Lee77ba1912012-04-05 19:36:12 +00001069void exynos4_set_lcd_clk(void)
1070{
1071 struct exynos4_clock *clk =
1072 (struct exynos4_clock *)samsung_get_base_clock();
Donghwa Lee77ba1912012-04-05 19:36:12 +00001073
1074 /*
1075 * CLK_GATE_BLOCK
1076 * CLK_CAM [0]
1077 * CLK_TV [1]
1078 * CLK_MFC [2]
1079 * CLK_G3D [3]
1080 * CLK_LCD0 [4]
1081 * CLK_LCD1 [5]
1082 * CLK_GPS [7]
1083 */
Inha Song4e558532014-02-06 14:20:12 +09001084 setbits_le32(&clk->gate_block, 1 << 4);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001085
1086 /*
1087 * CLK_SRC_LCD0
1088 * FIMD0_SEL [3:0]
1089 * MDNIE0_SEL [7:4]
1090 * MDNIE_PWM0_SEL [8:11]
1091 * MIPI0_SEL [12:15]
1092 * set lcd0 src clock 0x6: SCLK_MPLL
1093 */
Inha Song4e558532014-02-06 14:20:12 +09001094 clrsetbits_le32(&clk->src_lcd0, 0xf, 0x6);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001095
1096 /*
1097 * CLK_GATE_IP_LCD0
1098 * CLK_FIMD0 [0]
1099 * CLK_MIE0 [1]
1100 * CLK_MDNIE0 [2]
1101 * CLK_DSIM0 [3]
1102 * CLK_SMMUFIMD0 [4]
1103 * CLK_PPMULCD0 [5]
1104 * Gating all clocks for FIMD0
1105 */
Inha Song4e558532014-02-06 14:20:12 +09001106 setbits_le32(&clk->gate_ip_lcd0, 1 << 0);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001107
1108 /*
1109 * CLK_DIV_LCD0
1110 * FIMD0_RATIO [3:0]
1111 * MDNIE0_RATIO [7:4]
1112 * MDNIE_PWM0_RATIO [11:8]
1113 * MDNIE_PWM_PRE_RATIO [15:12]
1114 * MIPI0_RATIO [19:16]
1115 * MIPI0_PRE_RATIO [23:20]
1116 * set fimd ratio
1117 */
Inha Song4e558532014-02-06 14:20:12 +09001118 clrsetbits_le32(&clk->div_lcd0, 0xf, 0x1);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001119}
1120
Donghwa Lee3c9d4532012-07-02 01:15:49 +00001121void exynos5_set_lcd_clk(void)
1122{
1123 struct exynos5_clock *clk =
1124 (struct exynos5_clock *)samsung_get_base_clock();
Donghwa Lee3c9d4532012-07-02 01:15:49 +00001125
1126 /*
1127 * CLK_GATE_BLOCK
1128 * CLK_CAM [0]
1129 * CLK_TV [1]
1130 * CLK_MFC [2]
1131 * CLK_G3D [3]
1132 * CLK_LCD0 [4]
1133 * CLK_LCD1 [5]
1134 * CLK_GPS [7]
1135 */
Inha Song4e558532014-02-06 14:20:12 +09001136 setbits_le32(&clk->gate_block, 1 << 4);
Donghwa Lee3c9d4532012-07-02 01:15:49 +00001137
1138 /*
1139 * CLK_SRC_LCD0
1140 * FIMD0_SEL [3:0]
1141 * MDNIE0_SEL [7:4]
1142 * MDNIE_PWM0_SEL [8:11]
1143 * MIPI0_SEL [12:15]
1144 * set lcd0 src clock 0x6: SCLK_MPLL
1145 */
Inha Song4e558532014-02-06 14:20:12 +09001146 clrsetbits_le32(&clk->src_disp1_0, 0xf, 0x6);
Donghwa Lee3c9d4532012-07-02 01:15:49 +00001147
1148 /*
1149 * CLK_GATE_IP_LCD0
1150 * CLK_FIMD0 [0]
1151 * CLK_MIE0 [1]
1152 * CLK_MDNIE0 [2]
1153 * CLK_DSIM0 [3]
1154 * CLK_SMMUFIMD0 [4]
1155 * CLK_PPMULCD0 [5]
1156 * Gating all clocks for FIMD0
1157 */
Inha Song4e558532014-02-06 14:20:12 +09001158 setbits_le32(&clk->gate_ip_disp1, 1 << 0);
Donghwa Lee3c9d4532012-07-02 01:15:49 +00001159
1160 /*
1161 * CLK_DIV_LCD0
1162 * FIMD0_RATIO [3:0]
1163 * MDNIE0_RATIO [7:4]
1164 * MDNIE_PWM0_RATIO [11:8]
1165 * MDNIE_PWM_PRE_RATIO [15:12]
1166 * MIPI0_RATIO [19:16]
1167 * MIPI0_PRE_RATIO [23:20]
1168 * set fimd ratio
1169 */
Inha Song4e558532014-02-06 14:20:12 +09001170 clrsetbits_le32(&clk->div_disp1_0, 0xf, 0x0);
Donghwa Lee3c9d4532012-07-02 01:15:49 +00001171}
1172
Ajay Kumar914af872014-09-05 16:53:32 +05301173void exynos5420_set_lcd_clk(void)
1174{
1175 struct exynos5420_clock *clk =
1176 (struct exynos5420_clock *)samsung_get_base_clock();
1177 unsigned int cfg;
1178
1179 /*
1180 * CLK_SRC_DISP10
1181 * FIMD1_SEL [4]
1182 * 0: SCLK_RPLL
1183 * 1: SCLK_SPLL
1184 */
1185 cfg = readl(&clk->src_disp10);
1186 cfg &= ~(0x1 << 4);
1187 cfg |= (0 << 4);
1188 writel(cfg, &clk->src_disp10);
1189
1190 /*
1191 * CLK_DIV_DISP10
1192 * FIMD1_RATIO [3:0]
1193 */
1194 cfg = readl(&clk->div_disp10);
1195 cfg &= ~(0xf << 0);
1196 cfg |= (0 << 0);
1197 writel(cfg, &clk->div_disp10);
1198}
1199
Donghwa Lee77ba1912012-04-05 19:36:12 +00001200void exynos4_set_mipi_clk(void)
1201{
1202 struct exynos4_clock *clk =
1203 (struct exynos4_clock *)samsung_get_base_clock();
Donghwa Lee77ba1912012-04-05 19:36:12 +00001204
1205 /*
1206 * CLK_SRC_LCD0
1207 * FIMD0_SEL [3:0]
1208 * MDNIE0_SEL [7:4]
1209 * MDNIE_PWM0_SEL [8:11]
1210 * MIPI0_SEL [12:15]
1211 * set mipi0 src clock 0x6: SCLK_MPLL
1212 */
Inha Song4e558532014-02-06 14:20:12 +09001213 clrsetbits_le32(&clk->src_lcd0, 0xf << 12, 0x6 << 12);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001214
1215 /*
1216 * CLK_SRC_MASK_LCD0
1217 * FIMD0_MASK [0]
1218 * MDNIE0_MASK [4]
1219 * MDNIE_PWM0_MASK [8]
1220 * MIPI0_MASK [12]
1221 * set src mask mipi0 0x1: Unmask
1222 */
Inha Song4e558532014-02-06 14:20:12 +09001223 setbits_le32(&clk->src_mask_lcd0, 0x1 << 12);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001224
1225 /*
1226 * CLK_GATE_IP_LCD0
1227 * CLK_FIMD0 [0]
1228 * CLK_MIE0 [1]
1229 * CLK_MDNIE0 [2]
1230 * CLK_DSIM0 [3]
1231 * CLK_SMMUFIMD0 [4]
1232 * CLK_PPMULCD0 [5]
1233 * Gating all clocks for MIPI0
1234 */
Inha Song4e558532014-02-06 14:20:12 +09001235 setbits_le32(&clk->gate_ip_lcd0, 1 << 3);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001236
1237 /*
1238 * CLK_DIV_LCD0
1239 * FIMD0_RATIO [3:0]
1240 * MDNIE0_RATIO [7:4]
1241 * MDNIE_PWM0_RATIO [11:8]
1242 * MDNIE_PWM_PRE_RATIO [15:12]
1243 * MIPI0_RATIO [19:16]
1244 * MIPI0_PRE_RATIO [23:20]
1245 * set mipi ratio
1246 */
Inha Song4e558532014-02-06 14:20:12 +09001247 clrsetbits_le32(&clk->div_lcd0, 0xf << 16, 0x1 << 16);
Donghwa Lee77ba1912012-04-05 19:36:12 +00001248}
1249
Rajeshwari Shinde1c9412a2012-07-23 21:23:48 +00001250/*
1251 * I2C
1252 *
1253 * exynos5: obtaining the I2C clock
1254 */
1255static unsigned long exynos5_get_i2c_clk(void)
1256{
1257 struct exynos5_clock *clk =
1258 (struct exynos5_clock *)samsung_get_base_clock();
1259 unsigned long aclk_66, aclk_66_pre, sclk;
1260 unsigned int ratio;
1261
1262 sclk = get_pll_clk(MPLL);
1263
1264 ratio = (readl(&clk->div_top1)) >> 24;
1265 ratio &= 0x7;
1266 aclk_66_pre = sclk / (ratio + 1);
1267 ratio = readl(&clk->div_top0);
1268 ratio &= 0x7;
1269 aclk_66 = aclk_66_pre / (ratio + 1);
1270 return aclk_66;
1271}
1272
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001273int exynos5_set_epll_clk(unsigned long rate)
1274{
1275 unsigned int epll_con, epll_con_k;
1276 unsigned int i;
1277 unsigned int lockcnt;
1278 unsigned int start;
1279 struct exynos5_clock *clk =
1280 (struct exynos5_clock *)samsung_get_base_clock();
1281
1282 epll_con = readl(&clk->epll_con0);
1283 epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
1284 EPLL_CON0_LOCK_DET_EN_SHIFT) |
1285 EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
1286 EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
1287 EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
1288
1289 for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) {
1290 if (exynos5_epll_div[i].freq_out == rate)
1291 break;
1292 }
1293
1294 if (i == ARRAY_SIZE(exynos5_epll_div))
1295 return -1;
1296
1297 epll_con_k = exynos5_epll_div[i].k_dsm << 0;
1298 epll_con |= exynos5_epll_div[i].en_lock_det <<
1299 EPLL_CON0_LOCK_DET_EN_SHIFT;
1300 epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
1301 epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
1302 epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
1303
1304 /*
1305 * Required period ( in cycles) to genarate a stable clock output.
1306 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
1307 * frequency input (as per spec)
1308 */
1309 lockcnt = 3000 * exynos5_epll_div[i].p_div;
1310
1311 writel(lockcnt, &clk->epll_lock);
1312 writel(epll_con, &clk->epll_con0);
1313 writel(epll_con_k, &clk->epll_con1);
1314
1315 start = get_timer(0);
1316
1317 while (!(readl(&clk->epll_con0) &
1318 (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
1319 if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
1320 debug("%s: Timeout waiting for EPLL lock\n", __func__);
1321 return -1;
1322 }
1323 }
1324 return 0;
1325}
1326
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301327int exynos5_set_i2s_clk_source(unsigned int i2s_id)
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001328{
1329 struct exynos5_clock *clk =
1330 (struct exynos5_clock *)samsung_get_base_clock();
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301331 unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass();
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001332
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301333 if (i2s_id == 0) {
1334 setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL);
1335 clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK,
1336 (CLK_SRC_SCLK_EPLL));
1337 setbits_le32(audio_ass, AUDIO_CLKMUX_ASS);
1338 } else if (i2s_id == 1) {
1339 clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
1340 (CLK_SRC_SCLK_EPLL));
1341 } else {
1342 return -1;
1343 }
1344 return 0;
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001345}
1346
1347int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301348 unsigned int dst_frq,
1349 unsigned int i2s_id)
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001350{
1351 struct exynos5_clock *clk =
1352 (struct exynos5_clock *)samsung_get_base_clock();
1353 unsigned int div;
1354
1355 if ((dst_frq == 0) || (src_frq == 0)) {
1356 debug("%s: Invalid requency input for prescaler\n", __func__);
1357 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1358 return -1;
1359 }
1360
1361 div = (src_frq / dst_frq);
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301362 if (i2s_id == 0) {
1363 if (div > AUDIO_0_RATIO_MASK) {
1364 debug("%s: Frequency ratio is out of range\n",
1365 __func__);
1366 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1367 return -1;
1368 }
1369 clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK,
1370 (div & AUDIO_0_RATIO_MASK));
1371 } else if(i2s_id == 1) {
1372 if (div > AUDIO_1_RATIO_MASK) {
1373 debug("%s: Frequency ratio is out of range\n",
1374 __func__);
1375 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1376 return -1;
1377 }
1378 clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
1379 (div & AUDIO_1_RATIO_MASK));
1380 } else {
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001381 return -1;
1382 }
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001383 return 0;
1384}
1385
Hatim RVe6365b62012-11-02 01:15:34 +00001386/**
1387 * Linearly searches for the most accurate main and fine stage clock scalars
1388 * (divisors) for a specified target frequency and scalar bit sizes by checking
1389 * all multiples of main_scalar_bits values. Will always return scalars up to or
1390 * slower than target.
1391 *
1392 * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
1393 * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
1394 * @param input_freq Clock frequency to be scaled in Hz
1395 * @param target_freq Desired clock frequency in Hz
1396 * @param best_fine_scalar Pointer to store the fine stage divisor
1397 *
1398 * @return best_main_scalar Main scalar for desired frequency or -1 if none
1399 * found
1400 */
1401static int clock_calc_best_scalar(unsigned int main_scaler_bits,
1402 unsigned int fine_scalar_bits, unsigned int input_rate,
1403 unsigned int target_rate, unsigned int *best_fine_scalar)
1404{
1405 int i;
1406 int best_main_scalar = -1;
1407 unsigned int best_error = target_rate;
1408 const unsigned int cap = (1 << fine_scalar_bits) - 1;
1409 const unsigned int loops = 1 << main_scaler_bits;
1410
1411 debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
1412 target_rate, cap);
1413
1414 assert(best_fine_scalar != NULL);
1415 assert(main_scaler_bits <= fine_scalar_bits);
1416
1417 *best_fine_scalar = 1;
1418
1419 if (input_rate == 0 || target_rate == 0)
1420 return -1;
1421
1422 if (target_rate >= input_rate)
1423 return 1;
1424
1425 for (i = 1; i <= loops; i++) {
Masahiro Yamadadb204642014-11-07 03:03:31 +09001426 const unsigned int effective_div =
1427 max(min(input_rate / i / target_rate, cap), 1U);
Hatim RVe6365b62012-11-02 01:15:34 +00001428 const unsigned int effective_rate = input_rate / i /
1429 effective_div;
1430 const int error = target_rate - effective_rate;
1431
1432 debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
1433 effective_rate, error);
1434
1435 if (error >= 0 && error <= best_error) {
1436 best_error = error;
1437 best_main_scalar = i;
1438 *best_fine_scalar = effective_div;
1439 }
1440 }
1441
1442 return best_main_scalar;
1443}
1444
1445static int exynos5_set_spi_clk(enum periph_id periph_id,
1446 unsigned int rate)
1447{
1448 struct exynos5_clock *clk =
1449 (struct exynos5_clock *)samsung_get_base_clock();
1450 int main;
1451 unsigned int fine;
1452 unsigned shift, pre_shift;
1453 unsigned mask = 0xff;
1454 u32 *reg;
1455
1456 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1457 if (main < 0) {
1458 debug("%s: Cannot set clock rate for periph %d",
1459 __func__, periph_id);
1460 return -1;
1461 }
1462 main = main - 1;
1463 fine = fine - 1;
1464
1465 switch (periph_id) {
1466 case PERIPH_ID_SPI0:
1467 reg = &clk->div_peric1;
1468 shift = 0;
1469 pre_shift = 8;
1470 break;
1471 case PERIPH_ID_SPI1:
1472 reg = &clk->div_peric1;
1473 shift = 16;
1474 pre_shift = 24;
1475 break;
1476 case PERIPH_ID_SPI2:
1477 reg = &clk->div_peric2;
1478 shift = 0;
1479 pre_shift = 8;
1480 break;
1481 case PERIPH_ID_SPI3:
1482 reg = &clk->sclk_div_isp;
1483 shift = 0;
1484 pre_shift = 4;
1485 break;
1486 case PERIPH_ID_SPI4:
1487 reg = &clk->sclk_div_isp;
1488 shift = 12;
1489 pre_shift = 16;
1490 break;
1491 default:
1492 debug("%s: Unsupported peripheral ID %d\n", __func__,
1493 periph_id);
1494 return -1;
1495 }
1496 clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
1497 clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
1498
1499 return 0;
1500}
1501
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301502static int exynos5420_set_spi_clk(enum periph_id periph_id,
1503 unsigned int rate)
1504{
1505 struct exynos5420_clock *clk =
1506 (struct exynos5420_clock *)samsung_get_base_clock();
1507 int main;
1508 unsigned int fine;
1509 unsigned shift, pre_shift;
1510 unsigned div_mask = 0xf, pre_div_mask = 0xff;
1511 u32 *reg;
1512 u32 *pre_reg;
1513
1514 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1515 if (main < 0) {
1516 debug("%s: Cannot set clock rate for periph %d",
1517 __func__, periph_id);
1518 return -1;
1519 }
1520 main = main - 1;
1521 fine = fine - 1;
1522
1523 switch (periph_id) {
1524 case PERIPH_ID_SPI0:
1525 reg = &clk->div_peric1;
1526 shift = 20;
1527 pre_reg = &clk->div_peric4;
1528 pre_shift = 8;
1529 break;
1530 case PERIPH_ID_SPI1:
1531 reg = &clk->div_peric1;
1532 shift = 24;
1533 pre_reg = &clk->div_peric4;
1534 pre_shift = 16;
1535 break;
1536 case PERIPH_ID_SPI2:
1537 reg = &clk->div_peric1;
1538 shift = 28;
1539 pre_reg = &clk->div_peric4;
1540 pre_shift = 24;
1541 break;
1542 case PERIPH_ID_SPI3:
1543 reg = &clk->div_isp1;
1544 shift = 16;
1545 pre_reg = &clk->div_isp1;
1546 pre_shift = 0;
1547 break;
1548 case PERIPH_ID_SPI4:
1549 reg = &clk->div_isp1;
1550 shift = 20;
1551 pre_reg = &clk->div_isp1;
1552 pre_shift = 8;
1553 break;
1554 default:
1555 debug("%s: Unsupported peripheral ID %d\n", __func__,
1556 periph_id);
1557 return -1;
1558 }
1559
1560 clrsetbits_le32(reg, div_mask << shift, (main & div_mask) << shift);
1561 clrsetbits_le32(pre_reg, pre_div_mask << pre_shift,
1562 (fine & pre_div_mask) << pre_shift);
1563
1564 return 0;
1565}
1566
Piotr Wilczek01d589f2012-11-20 02:19:02 +00001567static unsigned long exynos4_get_i2c_clk(void)
1568{
1569 struct exynos4_clock *clk =
1570 (struct exynos4_clock *)samsung_get_base_clock();
1571 unsigned long sclk, aclk_100;
1572 unsigned int ratio;
1573
1574 sclk = get_pll_clk(APLL);
1575
1576 ratio = (readl(&clk->div_top)) >> 4;
1577 ratio &= 0xf;
1578 aclk_100 = sclk / (ratio + 1);
1579 return aclk_100;
Minkyu Kangb1b24682011-01-24 15:22:23 +09001580}
1581
1582unsigned long get_pll_clk(int pllreg)
1583{
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301584 if (cpu_is_exynos5()) {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301585 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301586 return exynos5420_get_pll_clk(pllreg);
Chander Kashyap34076a02012-02-05 23:01:46 +00001587 return exynos5_get_pll_clk(pllreg);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301588 } else {
Chander Kashyap400ab162012-10-07 01:43:17 +00001589 if (proid_is_exynos4412())
1590 return exynos4x12_get_pll_clk(pllreg);
Chander Kashyap34076a02012-02-05 23:01:46 +00001591 return exynos4_get_pll_clk(pllreg);
Chander Kashyap400ab162012-10-07 01:43:17 +00001592 }
Minkyu Kangb1b24682011-01-24 15:22:23 +09001593}
1594
1595unsigned long get_arm_clk(void)
1596{
Chander Kashyap34076a02012-02-05 23:01:46 +00001597 if (cpu_is_exynos5())
1598 return exynos5_get_arm_clk();
Chander Kashyap400ab162012-10-07 01:43:17 +00001599 else {
1600 if (proid_is_exynos4412())
1601 return exynos4x12_get_arm_clk();
Chander Kashyap34076a02012-02-05 23:01:46 +00001602 return exynos4_get_arm_clk();
Chander Kashyap400ab162012-10-07 01:43:17 +00001603 }
Minkyu Kangb1b24682011-01-24 15:22:23 +09001604}
1605
Rajeshwari Shinde1c9412a2012-07-23 21:23:48 +00001606unsigned long get_i2c_clk(void)
1607{
1608 if (cpu_is_exynos5()) {
1609 return exynos5_get_i2c_clk();
Piotr Wilczek01d589f2012-11-20 02:19:02 +00001610 } else if (cpu_is_exynos4()) {
1611 return exynos4_get_i2c_clk();
Rajeshwari Shinde1c9412a2012-07-23 21:23:48 +00001612 } else {
1613 debug("I2C clock is not set for this CPU\n");
1614 return 0;
1615 }
1616}
1617
Minkyu Kangb1b24682011-01-24 15:22:23 +09001618unsigned long get_pwm_clk(void)
1619{
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301620 if (cpu_is_exynos5()) {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301621 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301622 return exynos5420_get_pwm_clk();
Padmavathi Vennabb714162013-03-28 04:32:23 +00001623 return clock_get_periph_rate(PERIPH_ID_PWM0);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301624 } else {
Chander Kashyap400ab162012-10-07 01:43:17 +00001625 if (proid_is_exynos4412())
1626 return exynos4x12_get_pwm_clk();
Chander Kashyap34076a02012-02-05 23:01:46 +00001627 return exynos4_get_pwm_clk();
Chander Kashyap400ab162012-10-07 01:43:17 +00001628 }
Minkyu Kangb1b24682011-01-24 15:22:23 +09001629}
1630
1631unsigned long get_uart_clk(int dev_index)
1632{
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301633 if (cpu_is_exynos5()) {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301634 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301635 return exynos5420_get_uart_clk(dev_index);
Chander Kashyap34076a02012-02-05 23:01:46 +00001636 return exynos5_get_uart_clk(dev_index);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301637 } else {
Chander Kashyap400ab162012-10-07 01:43:17 +00001638 if (proid_is_exynos4412())
1639 return exynos4x12_get_uart_clk(dev_index);
Chander Kashyap34076a02012-02-05 23:01:46 +00001640 return exynos4_get_uart_clk(dev_index);
Chander Kashyap400ab162012-10-07 01:43:17 +00001641 }
Minkyu Kangb1b24682011-01-24 15:22:23 +09001642}
Jaehoon Chung9a772212011-05-17 21:19:17 +00001643
Jaehoon Chung8788e062012-12-27 22:30:32 +00001644unsigned long get_mmc_clk(int dev_index)
1645{
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301646 if (cpu_is_exynos5()) {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301647 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301648 return exynos5420_get_mmc_clk(dev_index);
Jaehoon Chung8788e062012-12-27 22:30:32 +00001649 return exynos5_get_mmc_clk(dev_index);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301650 } else {
Jaehoon Chung8788e062012-12-27 22:30:32 +00001651 return exynos4_get_mmc_clk(dev_index);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301652 }
Jaehoon Chung8788e062012-12-27 22:30:32 +00001653}
1654
Jaehoon Chung9a772212011-05-17 21:19:17 +00001655void set_mmc_clk(int dev_index, unsigned int div)
1656{
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301657 if (cpu_is_exynos5()) {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301658 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301659 exynos5420_set_mmc_clk(dev_index, div);
1660 else
1661 exynos5_set_mmc_clk(dev_index, div);
1662 } else {
Beomho Seo99660cc2014-05-16 13:59:47 +09001663 exynos4_set_mmc_clk(dev_index, div);
Chander Kashyap400ab162012-10-07 01:43:17 +00001664 }
Jaehoon Chung9a772212011-05-17 21:19:17 +00001665}
Donghwa Lee77ba1912012-04-05 19:36:12 +00001666
1667unsigned long get_lcd_clk(void)
1668{
1669 if (cpu_is_exynos4())
1670 return exynos4_get_lcd_clk();
Ajay Kumar914af872014-09-05 16:53:32 +05301671 else {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301672 if (proid_is_exynos5420() || proid_is_exynos5800())
Ajay Kumar914af872014-09-05 16:53:32 +05301673 return exynos5420_get_lcd_clk();
1674 else
1675 return exynos5_get_lcd_clk();
1676 }
Donghwa Lee77ba1912012-04-05 19:36:12 +00001677}
1678
1679void set_lcd_clk(void)
1680{
1681 if (cpu_is_exynos4())
1682 exynos4_set_lcd_clk();
Ajay Kumar914af872014-09-05 16:53:32 +05301683 else {
1684 if (proid_is_exynos5250())
1685 exynos5_set_lcd_clk();
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301686 else if (proid_is_exynos5420() || proid_is_exynos5800())
Ajay Kumar914af872014-09-05 16:53:32 +05301687 exynos5420_set_lcd_clk();
1688 }
Donghwa Lee77ba1912012-04-05 19:36:12 +00001689}
1690
1691void set_mipi_clk(void)
1692{
1693 if (cpu_is_exynos4())
1694 exynos4_set_mipi_clk();
1695}
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001696
Hatim RVe6365b62012-11-02 01:15:34 +00001697int set_spi_clk(int periph_id, unsigned int rate)
1698{
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301699 if (cpu_is_exynos5()) {
Akshay Saraswat9fba7b42014-11-13 22:38:15 +05301700 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301701 return exynos5420_set_spi_clk(periph_id, rate);
Hatim RVe6365b62012-11-02 01:15:34 +00001702 return exynos5_set_spi_clk(periph_id, rate);
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301703 } else {
Hatim RVe6365b62012-11-02 01:15:34 +00001704 return 0;
Rajeshwari Birjeac892d02013-12-26 09:44:21 +05301705 }
Hatim RVe6365b62012-11-02 01:15:34 +00001706}
1707
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301708int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
1709 unsigned int i2s_id)
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001710{
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001711 if (cpu_is_exynos5())
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301712 return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id);
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001713 else
1714 return 0;
1715}
1716
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301717int set_i2s_clk_source(unsigned int i2s_id)
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001718{
1719 if (cpu_is_exynos5())
Dani Krishna Mohan65c7ee62013-09-11 16:38:48 +05301720 return exynos5_set_i2s_clk_source(i2s_id);
1721 else
1722 return 0;
Rajeshwari Shinde392a73a2012-10-25 19:49:29 +00001723}
1724
1725int set_epll_clk(unsigned long rate)
1726{
1727 if (cpu_is_exynos5())
1728 return exynos5_set_epll_clk(rate);
1729 else
1730 return 0;
1731}