blob: 5257a485f8fd5e2e133a6db9480cd51aff7aa6da [file] [log] [blame]
Minkyu Kang008a3512011-01-24 15:22:23 +09001/*
2 * Copyright (C) 2010 Samsung Electronics
3 * Minkyu Kang <mk7.kang@samsung.com>
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Minkyu Kang008a3512011-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 RVb56b3042012-11-02 01:15:34 +000012#include <asm/arch/periph.h>
Minkyu Kang008a3512011-01-24 15:22:23 +090013
Minkyu Kange161f602013-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 Venna12a46a32013-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 {
Akshay Saraswatd606ded2015-02-04 15:59:59 +053023 enum periph_id id;
Padmavathi Venna12a46a32013-03-28 04:32:21 +000024 int8_t src_bit;
25 int8_t div_bit;
26 int8_t prediv_bit;
27};
28
Akshay Saraswatd606ded2015-02-04 15:59:59 +053029/* periph_id src_bit div_bit prediv_bit */
Minkyu Kang1501cc92014-01-29 17:03:58 +090030static struct clk_bit_info clk_bit_info[] = {
Akshay Saraswatd606ded2015-02-04 15:59:59 +053031 {PERIPH_ID_UART0, 0, 0, -1},
32 {PERIPH_ID_UART1, 4, 4, -1},
33 {PERIPH_ID_UART2, 8, 8, -1},
34 {PERIPH_ID_UART3, 12, 12, -1},
35 {PERIPH_ID_I2C0, -1, 24, 0},
36 {PERIPH_ID_I2C1, -1, 24, 0},
37 {PERIPH_ID_I2C2, -1, 24, 0},
38 {PERIPH_ID_I2C3, -1, 24, 0},
39 {PERIPH_ID_I2C4, -1, 24, 0},
40 {PERIPH_ID_I2C5, -1, 24, 0},
41 {PERIPH_ID_I2C6, -1, 24, 0},
42 {PERIPH_ID_I2C7, -1, 24, 0},
43 {PERIPH_ID_SPI0, 16, 0, 8},
44 {PERIPH_ID_SPI1, 20, 16, 24},
45 {PERIPH_ID_SPI2, 24, 0, 8},
46 {PERIPH_ID_SDMMC0, 0, 0, 8},
47 {PERIPH_ID_SDMMC1, 4, 16, 24},
48 {PERIPH_ID_SDMMC2, 8, 0, 8},
49 {PERIPH_ID_SDMMC3, 12, 16, 24},
50 {PERIPH_ID_I2S0, 0, 0, 4},
51 {PERIPH_ID_I2S1, 4, 12, 16},
52 {PERIPH_ID_SPI3, 0, 0, 4},
53 {PERIPH_ID_SPI4, 4, 12, 16},
54 {PERIPH_ID_SDMMC4, 16, 0, 8},
55 {PERIPH_ID_PWM0, 24, 0, -1},
56 {PERIPH_ID_PWM1, 24, 0, -1},
57 {PERIPH_ID_PWM2, 24, 0, -1},
58 {PERIPH_ID_PWM3, 24, 0, -1},
59 {PERIPH_ID_PWM4, 24, 0, -1},
60
61 {PERIPH_ID_NONE, -1, -1, -1},
Padmavathi Venna12a46a32013-03-28 04:32:21 +000062};
63
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +000064/* Epll Clock division values to achive different frequency output */
65static struct set_epll_con_val exynos5_epll_div[] = {
66 { 192000000, 0, 48, 3, 1, 0 },
67 { 180000000, 0, 45, 3, 1, 0 },
68 { 73728000, 1, 73, 3, 3, 47710 },
69 { 67737600, 1, 90, 4, 3, 20762 },
70 { 49152000, 0, 49, 3, 3, 9961 },
71 { 45158400, 0, 45, 3, 3, 10381 },
72 { 180633600, 0, 45, 3, 1, 10381 }
73};
74
Minkyu Kangbb6527b2012-10-15 01:58:00 +000075/* exynos: return pll clock frequency */
76static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
Minkyu Kang008a3512011-01-24 15:22:23 +090077{
Minkyu Kangbb6527b2012-10-15 01:58:00 +000078 unsigned long m, p, s = 0, mask, fout;
Minkyu Kange161f602013-07-05 19:08:33 +090079 unsigned int div;
Minkyu Kang008a3512011-01-24 15:22:23 +090080 unsigned int freq;
Minkyu Kang008a3512011-01-24 15:22:23 +090081 /*
82 * APLL_CON: MIDV [25:16]
83 * MPLL_CON: MIDV [25:16]
84 * EPLL_CON: MIDV [24:16]
85 * VPLL_CON: MIDV [24:16]
Minkyu Kangbb6527b2012-10-15 01:58:00 +000086 * BPLL_CON: MIDV [25:16]: Exynos5
Minkyu Kang008a3512011-01-24 15:22:23 +090087 */
Ajay Kumar496f0e42014-09-05 16:53:32 +053088 if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL ||
89 pllreg == SPLL)
Minkyu Kang008a3512011-01-24 15:22:23 +090090 mask = 0x3ff;
91 else
92 mask = 0x1ff;
93
94 m = (r >> 16) & mask;
95
96 /* PDIV [13:8] */
97 p = (r >> 8) & 0x3f;
98 /* SDIV [2:0] */
99 s = r & 0x7;
100
Chander Kashyap5e46f832012-02-05 23:01:45 +0000101 freq = CONFIG_SYS_CLK_FREQ;
Minkyu Kang008a3512011-01-24 15:22:23 +0900102
Rajeshwari Birje060c2272013-12-26 09:44:21 +0530103 if (pllreg == EPLL || pllreg == RPLL) {
Minkyu Kang008a3512011-01-24 15:22:23 +0900104 k = k & 0xffff;
105 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
Minkyu Kange161f602013-07-05 19:08:33 +0900106 fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s)));
Minkyu Kang008a3512011-01-24 15:22:23 +0900107 } else if (pllreg == VPLL) {
108 k = k & 0xfff;
Minkyu Kange161f602013-07-05 19:08:33 +0900109
110 /*
111 * Exynos4210
112 * FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV)
113 *
114 * Exynos4412
115 * FOUT = (MDIV + K / 65535) * FIN / (PDIV * 2^SDIV)
116 *
117 * Exynos5250
118 * FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV)
119 */
120 if (proid_is_exynos4210())
121 div = PLL_DIV_1024;
122 else if (proid_is_exynos4412())
123 div = PLL_DIV_65535;
Akshay Saraswataa14b422014-11-13 22:38:15 +0530124 else if (proid_is_exynos5250() || proid_is_exynos5420()
125 || proid_is_exynos5800())
Minkyu Kange161f602013-07-05 19:08:33 +0900126 div = PLL_DIV_65536;
127 else
128 return 0;
129
130 fout = (m + k / div) * (freq / (p * (1 << s)));
Minkyu Kang008a3512011-01-24 15:22:23 +0900131 } else {
Minkyu Kange161f602013-07-05 19:08:33 +0900132 /*
Łukasz Majewskif4eaf882013-07-12 19:08:25 +0200133 * Exynos4412 / Exynos5250
Minkyu Kange161f602013-07-05 19:08:33 +0900134 * FOUT = MDIV * FIN / (PDIV * 2^SDIV)
135 *
Łukasz Majewskif4eaf882013-07-12 19:08:25 +0200136 * Exynos4210
Minkyu Kange161f602013-07-05 19:08:33 +0900137 * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1))
138 */
139 if (proid_is_exynos4210())
Minkyu Kange161f602013-07-05 19:08:33 +0900140 fout = m * (freq / (p * (1 << (s - 1))));
Łukasz Majewskif4eaf882013-07-12 19:08:25 +0200141 else
142 fout = m * (freq / (p * (1 << s)));
Minkyu Kang008a3512011-01-24 15:22:23 +0900143 }
Minkyu Kang008a3512011-01-24 15:22:23 +0900144 return fout;
145}
146
Minkyu Kangbb6527b2012-10-15 01:58:00 +0000147/* exynos4: return pll clock frequency */
148static unsigned long exynos4_get_pll_clk(int pllreg)
149{
150 struct exynos4_clock *clk =
151 (struct exynos4_clock *)samsung_get_base_clock();
152 unsigned long r, k = 0;
153
154 switch (pllreg) {
155 case APLL:
156 r = readl(&clk->apll_con0);
157 break;
158 case MPLL:
159 r = readl(&clk->mpll_con0);
160 break;
161 case EPLL:
162 r = readl(&clk->epll_con0);
163 k = readl(&clk->epll_con1);
164 break;
165 case VPLL:
166 r = readl(&clk->vpll_con0);
167 k = readl(&clk->vpll_con1);
168 break;
169 default:
170 printf("Unsupported PLL (%d)\n", pllreg);
171 return 0;
172 }
173
174 return exynos_get_pll_clk(pllreg, r, k);
175}
176
Chander Kashyapa5277572012-10-07 01:43:17 +0000177/* exynos4x12: return pll clock frequency */
178static unsigned long exynos4x12_get_pll_clk(int pllreg)
179{
180 struct exynos4x12_clock *clk =
181 (struct exynos4x12_clock *)samsung_get_base_clock();
182 unsigned long r, k = 0;
183
184 switch (pllreg) {
185 case APLL:
186 r = readl(&clk->apll_con0);
187 break;
188 case MPLL:
189 r = readl(&clk->mpll_con0);
190 break;
191 case EPLL:
192 r = readl(&clk->epll_con0);
193 k = readl(&clk->epll_con1);
194 break;
195 case VPLL:
196 r = readl(&clk->vpll_con0);
197 k = readl(&clk->vpll_con1);
198 break;
199 default:
200 printf("Unsupported PLL (%d)\n", pllreg);
201 return 0;
202 }
203
204 return exynos_get_pll_clk(pllreg, r, k);
205}
206
Chander Kashyap37bb6d82012-02-05 23:01:46 +0000207/* exynos5: return pll clock frequency */
208static unsigned long exynos5_get_pll_clk(int pllreg)
209{
210 struct exynos5_clock *clk =
211 (struct exynos5_clock *)samsung_get_base_clock();
Minkyu Kangbb6527b2012-10-15 01:58:00 +0000212 unsigned long r, k = 0, fout;
213 unsigned int pll_div2_sel, fout_sel;
Chander Kashyap37bb6d82012-02-05 23:01:46 +0000214
215 switch (pllreg) {
216 case APLL:
217 r = readl(&clk->apll_con0);
218 break;
219 case MPLL:
220 r = readl(&clk->mpll_con0);
221 break;
222 case EPLL:
223 r = readl(&clk->epll_con0);
224 k = readl(&clk->epll_con1);
225 break;
226 case VPLL:
227 r = readl(&clk->vpll_con0);
228 k = readl(&clk->vpll_con1);
229 break;
Rajeshwari Shinde10bc1a72012-07-03 20:02:58 +0000230 case BPLL:
231 r = readl(&clk->bpll_con0);
232 break;
Chander Kashyap37bb6d82012-02-05 23:01:46 +0000233 default:
234 printf("Unsupported PLL (%d)\n", pllreg);
235 return 0;
236 }
237
Minkyu Kangbb6527b2012-10-15 01:58:00 +0000238 fout = exynos_get_pll_clk(pllreg, r, k);
Chander Kashyap37bb6d82012-02-05 23:01:46 +0000239
Rajeshwari Shinde10bc1a72012-07-03 20:02:58 +0000240 /* According to the user manual, in EVT1 MPLL and BPLL always gives
Rajeshwari Shinde6071bca2012-07-03 20:02:57 +0000241 * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
Rajeshwari Shinde10bc1a72012-07-03 20:02:58 +0000242 if (pllreg == MPLL || pllreg == BPLL) {
Rajeshwari Shinde6071bca2012-07-03 20:02:57 +0000243 pll_div2_sel = readl(&clk->pll_div2_sel);
Rajeshwari Shinde10bc1a72012-07-03 20:02:58 +0000244
245 switch (pllreg) {
246 case MPLL:
247 fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
248 & MPLL_FOUT_SEL_MASK;
249 break;
250 case BPLL:
251 fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
252 & BPLL_FOUT_SEL_MASK;
253 break;
Jaehoon Chungf8c5cfa2012-07-09 21:20:34 +0000254 default:
255 fout_sel = -1;
256 break;
Rajeshwari Shinde10bc1a72012-07-03 20:02:58 +0000257 }
258
259 if (fout_sel == 0)
Rajeshwari Shinde6071bca2012-07-03 20:02:57 +0000260 fout /= 2;
261 }
262
Chander Kashyap37bb6d82012-02-05 23:01:46 +0000263 return fout;
264}
265
Akshay Saraswat325eb182015-02-04 16:00:00 +0530266/* exynos542x: return pll clock frequency */
267static unsigned long exynos542x_get_pll_clk(int pllreg)
268{
269 struct exynos5420_clock *clk =
270 (struct exynos5420_clock *)samsung_get_base_clock();
271 unsigned long r, k = 0;
272
273 switch (pllreg) {
274 case APLL:
275 r = readl(&clk->apll_con0);
276 break;
277 case MPLL:
278 r = readl(&clk->mpll_con0);
279 break;
280 case EPLL:
281 r = readl(&clk->epll_con0);
282 k = readl(&clk->epll_con1);
283 break;
284 case VPLL:
285 r = readl(&clk->vpll_con0);
286 k = readl(&clk->vpll_con1);
287 break;
288 case BPLL:
289 r = readl(&clk->bpll_con0);
290 break;
291 case RPLL:
292 r = readl(&clk->rpll_con0);
293 k = readl(&clk->rpll_con1);
294 break;
295 case SPLL:
296 r = readl(&clk->spll_con0);
297 break;
298 default:
299 printf("Unsupported PLL (%d)\n", pllreg);
300 return 0;
301 }
302
303 return exynos_get_pll_clk(pllreg, r, k);
304}
305
Akshay Saraswatd606ded2015-02-04 15:59:59 +0530306static struct clk_bit_info *get_clk_bit_info(int peripheral)
307{
308 int i;
309
310 for (i = 0; clk_bit_info[i].id != PERIPH_ID_NONE; i++) {
311 if (clk_bit_info[i].id == peripheral)
312 break;
313 }
314
315 if (clk_bit_info[i].id == PERIPH_ID_NONE)
316 debug("ERROR: Peripheral ID %d not found\n", peripheral);
317
318 return &clk_bit_info[i];
319}
320
Padmavathi Venna12a46a32013-03-28 04:32:21 +0000321static unsigned long exynos5_get_periph_rate(int peripheral)
322{
Akshay Saraswatd606ded2015-02-04 15:59:59 +0530323 struct clk_bit_info *bit_info = get_clk_bit_info(peripheral);
Padmavathi Venna12a46a32013-03-28 04:32:21 +0000324 unsigned long sclk, sub_clk;
325 unsigned int src, div, sub_div;
326 struct exynos5_clock *clk =
327 (struct exynos5_clock *)samsung_get_base_clock();
328
329 switch (peripheral) {
330 case PERIPH_ID_UART0:
331 case PERIPH_ID_UART1:
332 case PERIPH_ID_UART2:
333 case PERIPH_ID_UART3:
334 src = readl(&clk->src_peric0);
335 div = readl(&clk->div_peric0);
336 break;
337 case PERIPH_ID_PWM0:
338 case PERIPH_ID_PWM1:
339 case PERIPH_ID_PWM2:
340 case PERIPH_ID_PWM3:
341 case PERIPH_ID_PWM4:
342 src = readl(&clk->src_peric0);
343 div = readl(&clk->div_peric3);
344 break;
Dani Krishna Mohan3dd22a32013-09-11 16:38:48 +0530345 case PERIPH_ID_I2S0:
346 src = readl(&clk->src_mau);
347 div = readl(&clk->div_mau);
Padmavathi Venna12a46a32013-03-28 04:32:21 +0000348 case PERIPH_ID_SPI0:
349 case PERIPH_ID_SPI1:
350 src = readl(&clk->src_peric1);
351 div = readl(&clk->div_peric1);
352 break;
353 case PERIPH_ID_SPI2:
354 src = readl(&clk->src_peric1);
355 div = readl(&clk->div_peric2);
356 break;
357 case PERIPH_ID_SPI3:
358 case PERIPH_ID_SPI4:
359 src = readl(&clk->sclk_src_isp);
360 div = readl(&clk->sclk_div_isp);
361 break;
362 case PERIPH_ID_SDMMC0:
363 case PERIPH_ID_SDMMC1:
364 case PERIPH_ID_SDMMC2:
365 case PERIPH_ID_SDMMC3:
366 src = readl(&clk->src_fsys);
367 div = readl(&clk->div_fsys1);
368 break;
369 case PERIPH_ID_I2C0:
370 case PERIPH_ID_I2C1:
371 case PERIPH_ID_I2C2:
372 case PERIPH_ID_I2C3:
373 case PERIPH_ID_I2C4:
374 case PERIPH_ID_I2C5:
375 case PERIPH_ID_I2C6:
376 case PERIPH_ID_I2C7:
377 sclk = exynos5_get_pll_clk(MPLL);
378 sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit)
379 & 0x7) + 1;
380 div = ((readl(&clk->div_top0) >> bit_info->prediv_bit)
381 & 0x7) + 1;
382 return (sclk / sub_div) / div;
383 default:
384 debug("%s: invalid peripheral %d", __func__, peripheral);
385 return -1;
386 };
387
388 src = (src >> bit_info->src_bit) & 0xf;
389
390 switch (src) {
391 case EXYNOS_SRC_MPLL:
392 sclk = exynos5_get_pll_clk(MPLL);
393 break;
394 case EXYNOS_SRC_EPLL:
395 sclk = exynos5_get_pll_clk(EPLL);
396 break;
397 case EXYNOS_SRC_VPLL:
398 sclk = exynos5_get_pll_clk(VPLL);
399 break;
400 default:
401 return 0;
402 }
403
404 /* Ratio clock division for this peripheral */
405 sub_div = (div >> bit_info->div_bit) & 0xf;
406 sub_clk = sclk / (sub_div + 1);
407
408 /* Pre-ratio clock division for SDMMC0 and 2 */
409 if (peripheral == PERIPH_ID_SDMMC0 || peripheral == PERIPH_ID_SDMMC2) {
410 div = (div >> bit_info->prediv_bit) & 0xff;
411 return sub_clk / (div + 1);
412 }
413
414 return sub_clk;
415}
416
417unsigned long clock_get_periph_rate(int peripheral)
418{
419 if (cpu_is_exynos5())
420 return exynos5_get_periph_rate(peripheral);
421 else
422 return 0;
423}
424
Chander Kashyap393cb362011-12-06 23:34:12 +0000425/* exynos4: return ARM clock frequency */
426static unsigned long exynos4_get_arm_clk(void)
Minkyu Kang008a3512011-01-24 15:22:23 +0900427{
Chander Kashyap393cb362011-12-06 23:34:12 +0000428 struct exynos4_clock *clk =
429 (struct exynos4_clock *)samsung_get_base_clock();
Minkyu Kang008a3512011-01-24 15:22:23 +0900430 unsigned long div;
Chander Kashyapdb68bc22011-12-18 22:56:44 +0000431 unsigned long armclk;
432 unsigned int core_ratio;
433 unsigned int core2_ratio;
Minkyu Kang008a3512011-01-24 15:22:23 +0900434
435 div = readl(&clk->div_cpu0);
436
Chander Kashyapdb68bc22011-12-18 22:56:44 +0000437 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
438 core_ratio = (div >> 0) & 0x7;
439 core2_ratio = (div >> 28) & 0x7;
Minkyu Kang008a3512011-01-24 15:22:23 +0900440
Chander Kashyapdb68bc22011-12-18 22:56:44 +0000441 armclk = get_pll_clk(APLL) / (core_ratio + 1);
442 armclk /= (core2_ratio + 1);
Minkyu Kang008a3512011-01-24 15:22:23 +0900443
Chander Kashyapdb68bc22011-12-18 22:56:44 +0000444 return armclk;
Minkyu Kang008a3512011-01-24 15:22:23 +0900445}
446
Chander Kashyapa5277572012-10-07 01:43:17 +0000447/* exynos4x12: return ARM clock frequency */
448static unsigned long exynos4x12_get_arm_clk(void)
449{
450 struct exynos4x12_clock *clk =
451 (struct exynos4x12_clock *)samsung_get_base_clock();
452 unsigned long div;
453 unsigned long armclk;
454 unsigned int core_ratio;
455 unsigned int core2_ratio;
456
457 div = readl(&clk->div_cpu0);
458
459 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
460 core_ratio = (div >> 0) & 0x7;
461 core2_ratio = (div >> 28) & 0x7;
462
463 armclk = get_pll_clk(APLL) / (core_ratio + 1);
464 armclk /= (core2_ratio + 1);
465
466 return armclk;
467}
468
Chander Kashyap37bb6d82012-02-05 23:01:46 +0000469/* exynos5: return ARM clock frequency */
470static unsigned long exynos5_get_arm_clk(void)
471{
472 struct exynos5_clock *clk =
473 (struct exynos5_clock *)samsung_get_base_clock();
474 unsigned long div;
475 unsigned long armclk;
476 unsigned int arm_ratio;
477 unsigned int arm2_ratio;
478
479 div = readl(&clk->div_cpu0);
480
481 /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
482 arm_ratio = (div >> 0) & 0x7;
483 arm2_ratio = (div >> 28) & 0x7;
484
485 armclk = get_pll_clk(APLL) / (arm_ratio + 1);
486 armclk /= (arm2_ratio + 1);
487
488 return armclk;
489}
490
Chander Kashyap393cb362011-12-06 23:34:12 +0000491/* exynos4: return pwm clock frequency */
492static unsigned long exynos4_get_pwm_clk(void)
Minkyu Kang008a3512011-01-24 15:22:23 +0900493{
Chander Kashyap393cb362011-12-06 23:34:12 +0000494 struct exynos4_clock *clk =
495 (struct exynos4_clock *)samsung_get_base_clock();
Minkyu Kang008a3512011-01-24 15:22:23 +0900496 unsigned long pclk, sclk;
497 unsigned int sel;
498 unsigned int ratio;
499
Minkyu Kangb4f73912011-05-18 16:57:55 +0900500 if (s5p_get_cpu_rev() == 0) {
501 /*
502 * CLK_SRC_PERIL0
503 * PWM_SEL [27:24]
504 */
505 sel = readl(&clk->src_peril0);
506 sel = (sel >> 24) & 0xf;
Minkyu Kang008a3512011-01-24 15:22:23 +0900507
Minkyu Kangb4f73912011-05-18 16:57:55 +0900508 if (sel == 0x6)
509 sclk = get_pll_clk(MPLL);
510 else if (sel == 0x7)
511 sclk = get_pll_clk(EPLL);
512 else if (sel == 0x8)
513 sclk = get_pll_clk(VPLL);
514 else
515 return 0;
516
517 /*
518 * CLK_DIV_PERIL3
519 * PWM_RATIO [3:0]
520 */
521 ratio = readl(&clk->div_peril3);
522 ratio = ratio & 0xf;
523 } else if (s5p_get_cpu_rev() == 1) {
Minkyu Kang008a3512011-01-24 15:22:23 +0900524 sclk = get_pll_clk(MPLL);
Minkyu Kangb4f73912011-05-18 16:57:55 +0900525 ratio = 8;
526 } else
Minkyu Kang008a3512011-01-24 15:22:23 +0900527 return 0;
528
Minkyu Kang008a3512011-01-24 15:22:23 +0900529 pclk = sclk / (ratio + 1);
530
531 return pclk;
532}
533
Chander Kashyapa5277572012-10-07 01:43:17 +0000534/* exynos4x12: return pwm clock frequency */
535static unsigned long exynos4x12_get_pwm_clk(void)
536{
537 unsigned long pclk, sclk;
538 unsigned int ratio;
539
540 sclk = get_pll_clk(MPLL);
541 ratio = 8;
542
543 pclk = sclk / (ratio + 1);
544
545 return pclk;
546}
547
Rajeshwari Birje060c2272013-12-26 09:44:21 +0530548/* exynos5420: return pwm clock frequency */
549static unsigned long exynos5420_get_pwm_clk(void)
550{
551 struct exynos5420_clock *clk =
552 (struct exynos5420_clock *)samsung_get_base_clock();
553 unsigned long pclk, sclk;
554 unsigned int ratio;
555
556 /*
557 * CLK_DIV_PERIC0
558 * PWM_RATIO [31:28]
559 */
560 ratio = readl(&clk->div_peric0);
561 ratio = (ratio >> 28) & 0xf;
562 sclk = get_pll_clk(MPLL);
563
564 pclk = sclk / (ratio + 1);
565
566 return pclk;
567}
568
Chander Kashyap393cb362011-12-06 23:34:12 +0000569/* exynos4: return uart clock frequency */
570static unsigned long exynos4_get_uart_clk(int dev_index)
Minkyu Kang008a3512011-01-24 15:22:23 +0900571{
Chander Kashyap393cb362011-12-06 23:34:12 +0000572 struct exynos4_clock *clk =
573 (struct exynos4_clock *)samsung_get_base_clock();
Minkyu Kang008a3512011-01-24 15:22:23 +0900574 unsigned long uclk, sclk;
575 unsigned int sel;
576 unsigned int ratio;
577
578 /*
579 * CLK_SRC_PERIL0
580 * UART0_SEL [3:0]
581 * UART1_SEL [7:4]
582 * UART2_SEL [8:11]
583 * UART3_SEL [12:15]
584 * UART4_SEL [16:19]
585 * UART5_SEL [23:20]
586 */
587 sel = readl(&clk->src_peril0);
588 sel = (sel >> (dev_index << 2)) & 0xf;
589
590 if (sel == 0x6)
591 sclk = get_pll_clk(MPLL);
592 else if (sel == 0x7)
593 sclk = get_pll_clk(EPLL);
594 else if (sel == 0x8)
595 sclk = get_pll_clk(VPLL);
596 else
597 return 0;
598
599 /*
600 * CLK_DIV_PERIL0
601 * UART0_RATIO [3:0]
602 * UART1_RATIO [7:4]
603 * UART2_RATIO [8:11]
604 * UART3_RATIO [12:15]
605 * UART4_RATIO [16:19]
606 * UART5_RATIO [23:20]
607 */
608 ratio = readl(&clk->div_peril0);
609 ratio = (ratio >> (dev_index << 2)) & 0xf;
610
611 uclk = sclk / (ratio + 1);
612
613 return uclk;
614}
615
Chander Kashyapa5277572012-10-07 01:43:17 +0000616/* exynos4x12: return uart clock frequency */
617static unsigned long exynos4x12_get_uart_clk(int dev_index)
618{
619 struct exynos4x12_clock *clk =
620 (struct exynos4x12_clock *)samsung_get_base_clock();
621 unsigned long uclk, sclk;
622 unsigned int sel;
623 unsigned int ratio;
624
625 /*
626 * CLK_SRC_PERIL0
627 * UART0_SEL [3:0]
628 * UART1_SEL [7:4]
629 * UART2_SEL [8:11]
630 * UART3_SEL [12:15]
631 * UART4_SEL [16:19]
632 */
633 sel = readl(&clk->src_peril0);
634 sel = (sel >> (dev_index << 2)) & 0xf;
635
636 if (sel == 0x6)
637 sclk = get_pll_clk(MPLL);
638 else if (sel == 0x7)
639 sclk = get_pll_clk(EPLL);
640 else if (sel == 0x8)
641 sclk = get_pll_clk(VPLL);
642 else
643 return 0;
644
645 /*
646 * CLK_DIV_PERIL0
647 * UART0_RATIO [3:0]
648 * UART1_RATIO [7:4]
649 * UART2_RATIO [8:11]
650 * UART3_RATIO [12:15]
651 * UART4_RATIO [16:19]
652 */
653 ratio = readl(&clk->div_peril0);
654 ratio = (ratio >> (dev_index << 2)) & 0xf;
655
656 uclk = sclk / (ratio + 1);
657
658 return uclk;
659}
660
Chander Kashyap37bb6d82012-02-05 23:01:46 +0000661/* exynos5: return uart clock frequency */
662static unsigned long exynos5_get_uart_clk(int dev_index)
663{
664 struct exynos5_clock *clk =
665 (struct exynos5_clock *)samsung_get_base_clock();
666 unsigned long uclk, sclk;
667 unsigned int sel;
668 unsigned int ratio;
669
670 /*
671 * CLK_SRC_PERIC0
672 * UART0_SEL [3:0]
673 * UART1_SEL [7:4]
674 * UART2_SEL [8:11]
675 * UART3_SEL [12:15]
676 * UART4_SEL [16:19]
677 * UART5_SEL [23:20]
678 */
679 sel = readl(&clk->src_peric0);
680 sel = (sel >> (dev_index << 2)) & 0xf;
681
682 if (sel == 0x6)
683 sclk = get_pll_clk(MPLL);
684 else if (sel == 0x7)
685 sclk = get_pll_clk(EPLL);
686 else if (sel == 0x8)
687 sclk = get_pll_clk(VPLL);
688 else
689 return 0;
690
691 /*
692 * CLK_DIV_PERIC0
693 * UART0_RATIO [3:0]
694 * UART1_RATIO [7:4]
695 * UART2_RATIO [8:11]
696 * UART3_RATIO [12:15]
697 * UART4_RATIO [16:19]
698 * UART5_RATIO [23:20]
699 */
700 ratio = readl(&clk->div_peric0);
701 ratio = (ratio >> (dev_index << 2)) & 0xf;
702
703 uclk = sclk / (ratio + 1);
704
705 return uclk;
706}
707
Rajeshwari Birje060c2272013-12-26 09:44:21 +0530708/* exynos5420: return uart clock frequency */
709static unsigned long exynos5420_get_uart_clk(int dev_index)
710{
711 struct exynos5420_clock *clk =
712 (struct exynos5420_clock *)samsung_get_base_clock();
713 unsigned long uclk, sclk;
714 unsigned int sel;
715 unsigned int ratio;
716
717 /*
718 * CLK_SRC_PERIC0
719 * UART0_SEL [6:4]
720 * UART1_SEL [10:8]
721 * UART2_SEL [14:12]
722 * UART3_SEL [18:16]
723 * generalised calculation as follows
724 * sel = (sel >> ((dev_index * 4) + 4)) & mask;
725 */
726 sel = readl(&clk->src_peric0);
727 sel = (sel >> ((dev_index * 4) + 4)) & 0x7;
728
729 if (sel == 0x3)
730 sclk = get_pll_clk(MPLL);
731 else if (sel == 0x6)
732 sclk = get_pll_clk(EPLL);
733 else if (sel == 0x7)
734 sclk = get_pll_clk(RPLL);
735 else
736 return 0;
737
738 /*
739 * CLK_DIV_PERIC0
740 * UART0_RATIO [11:8]
741 * UART1_RATIO [15:12]
742 * UART2_RATIO [19:16]
743 * UART3_RATIO [23:20]
744 * generalised calculation as follows
745 * ratio = (ratio >> ((dev_index * 4) + 8)) & mask;
746 */
747 ratio = readl(&clk->div_peric0);
748 ratio = (ratio >> ((dev_index * 4) + 8)) & 0xf;
749
750 uclk = sclk / (ratio + 1);
751
752 return uclk;
753}
754
Jaehoon Chungc39e9692012-12-27 22:30:32 +0000755static unsigned long exynos4_get_mmc_clk(int dev_index)
756{
757 struct exynos4_clock *clk =
758 (struct exynos4_clock *)samsung_get_base_clock();
759 unsigned long uclk, sclk;
760 unsigned int sel, ratio, pre_ratio;
Amar2b81c262013-04-27 11:42:56 +0530761 int shift = 0;
Jaehoon Chungc39e9692012-12-27 22:30:32 +0000762
763 sel = readl(&clk->src_fsys);
764 sel = (sel >> (dev_index << 2)) & 0xf;
765
766 if (sel == 0x6)
767 sclk = get_pll_clk(MPLL);
768 else if (sel == 0x7)
769 sclk = get_pll_clk(EPLL);
770 else if (sel == 0x8)
771 sclk = get_pll_clk(VPLL);
772 else
773 return 0;
774
775 switch (dev_index) {
776 case 0:
777 case 1:
778 ratio = readl(&clk->div_fsys1);
779 pre_ratio = readl(&clk->div_fsys1);
780 break;
781 case 2:
782 case 3:
783 ratio = readl(&clk->div_fsys2);
784 pre_ratio = readl(&clk->div_fsys2);
785 break;
786 case 4:
787 ratio = readl(&clk->div_fsys3);
788 pre_ratio = readl(&clk->div_fsys3);
789 break;
790 default:
791 return 0;
792 }
793
794 if (dev_index == 1 || dev_index == 3)
795 shift = 16;
796
797 ratio = (ratio >> shift) & 0xf;
798 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
799 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
800
801 return uclk;
802}
803
804static unsigned long exynos5_get_mmc_clk(int dev_index)
805{
806 struct exynos5_clock *clk =
807 (struct exynos5_clock *)samsung_get_base_clock();
808 unsigned long uclk, sclk;
809 unsigned int sel, ratio, pre_ratio;
Amar2b81c262013-04-27 11:42:56 +0530810 int shift = 0;
Jaehoon Chungc39e9692012-12-27 22:30:32 +0000811
812 sel = readl(&clk->src_fsys);
813 sel = (sel >> (dev_index << 2)) & 0xf;
814
815 if (sel == 0x6)
816 sclk = get_pll_clk(MPLL);
817 else if (sel == 0x7)
818 sclk = get_pll_clk(EPLL);
819 else if (sel == 0x8)
820 sclk = get_pll_clk(VPLL);
821 else
822 return 0;
823
824 switch (dev_index) {
825 case 0:
826 case 1:
827 ratio = readl(&clk->div_fsys1);
828 pre_ratio = readl(&clk->div_fsys1);
829 break;
830 case 2:
831 case 3:
832 ratio = readl(&clk->div_fsys2);
833 pre_ratio = readl(&clk->div_fsys2);
834 break;
835 default:
836 return 0;
837 }
838
839 if (dev_index == 1 || dev_index == 3)
840 shift = 16;
841
842 ratio = (ratio >> shift) & 0xf;
843 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
844 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
845
846 return uclk;
847}
848
Rajeshwari Birje060c2272013-12-26 09:44:21 +0530849static unsigned long exynos5420_get_mmc_clk(int dev_index)
850{
851 struct exynos5420_clock *clk =
852 (struct exynos5420_clock *)samsung_get_base_clock();
853 unsigned long uclk, sclk;
854 unsigned int sel, ratio;
855
856 /*
857 * CLK_SRC_FSYS
858 * MMC0_SEL [10:8]
859 * MMC1_SEL [14:12]
860 * MMC2_SEL [18:16]
861 * generalised calculation as follows
862 * sel = (sel >> ((dev_index * 4) + 8)) & mask
863 */
864 sel = readl(&clk->src_fsys);
865 sel = (sel >> ((dev_index * 4) + 8)) & 0x7;
866
867 if (sel == 0x3)
868 sclk = get_pll_clk(MPLL);
Joonyoung Shimfb564352014-12-22 19:46:30 +0900869 else if (sel == 0x4)
870 sclk = get_pll_clk(SPLL);
Rajeshwari Birje060c2272013-12-26 09:44:21 +0530871 else if (sel == 0x6)
872 sclk = get_pll_clk(EPLL);
873 else
874 return 0;
875
876 /*
877 * CLK_DIV_FSYS1
878 * MMC0_RATIO [9:0]
879 * MMC1_RATIO [19:10]
880 * MMC2_RATIO [29:20]
881 * generalised calculation as follows
882 * ratio = (ratio >> (dev_index * 10)) & mask
883 */
884 ratio = readl(&clk->div_fsys1);
885 ratio = (ratio >> (dev_index * 10)) & 0x3ff;
886
887 uclk = (sclk / (ratio + 1));
888
889 return uclk;
890}
891
Chander Kashyap393cb362011-12-06 23:34:12 +0000892/* exynos4: set the mmc clock */
893static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
Jaehoon Chung68a8cbf2011-05-17 21:19:17 +0000894{
Chander Kashyap393cb362011-12-06 23:34:12 +0000895 struct exynos4_clock *clk =
896 (struct exynos4_clock *)samsung_get_base_clock();
Jaehoon Chung39c49752014-05-16 13:59:50 +0900897 unsigned int addr, clear_bit, set_bit;
Jaehoon Chung68a8cbf2011-05-17 21:19:17 +0000898
899 /*
900 * CLK_DIV_FSYS1
901 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
902 * CLK_DIV_FSYS2
903 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
Jaehoon Chung5374d382012-12-27 22:30:33 +0000904 * CLK_DIV_FSYS3
Jaehoon Chung39c49752014-05-16 13:59:50 +0900905 * MMC4_RATIO [3:0]
Jaehoon Chung68a8cbf2011-05-17 21:19:17 +0000906 */
907 if (dev_index < 2) {
908 addr = (unsigned int)&clk->div_fsys1;
Jaehoon Chung39c49752014-05-16 13:59:50 +0900909 clear_bit = MASK_PRE_RATIO(dev_index);
910 set_bit = SET_PRE_RATIO(dev_index, div);
911 } else if (dev_index == 4) {
Jaehoon Chung5374d382012-12-27 22:30:33 +0000912 addr = (unsigned int)&clk->div_fsys3;
913 dev_index -= 4;
Jaehoon Chung39c49752014-05-16 13:59:50 +0900914 /* MMC4 is controlled with the MMC4_RATIO value */
915 clear_bit = MASK_RATIO(dev_index);
916 set_bit = SET_RATIO(dev_index, div);
Jaehoon Chung68a8cbf2011-05-17 21:19:17 +0000917 } else {
918 addr = (unsigned int)&clk->div_fsys2;
919 dev_index -= 2;
Jaehoon Chung39c49752014-05-16 13:59:50 +0900920 clear_bit = MASK_PRE_RATIO(dev_index);
921 set_bit = SET_PRE_RATIO(dev_index, div);
Jaehoon Chung68a8cbf2011-05-17 21:19:17 +0000922 }
923
Jaehoon Chung39c49752014-05-16 13:59:50 +0900924 clrsetbits_le32(addr, clear_bit, set_bit);
Jaehoon Chung68a8cbf2011-05-17 21:19:17 +0000925}
926
Chander Kashyap37bb6d82012-02-05 23:01:46 +0000927/* exynos5: set the mmc clock */
928static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
929{
930 struct exynos5_clock *clk =
931 (struct exynos5_clock *)samsung_get_base_clock();
932 unsigned int addr;
Chander Kashyap37bb6d82012-02-05 23:01:46 +0000933
934 /*
935 * CLK_DIV_FSYS1
936 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
937 * CLK_DIV_FSYS2
938 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
939 */
940 if (dev_index < 2) {
941 addr = (unsigned int)&clk->div_fsys1;
942 } else {
943 addr = (unsigned int)&clk->div_fsys2;
944 dev_index -= 2;
945 }
946
Inha Songe25bfec2014-02-06 14:20:12 +0900947 clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8),
948 (div & 0xff) << ((dev_index << 4) + 8));
Chander Kashyap37bb6d82012-02-05 23:01:46 +0000949}
950
Rajeshwari Birje060c2272013-12-26 09:44:21 +0530951/* exynos5: set the mmc clock */
952static void exynos5420_set_mmc_clk(int dev_index, unsigned int div)
953{
954 struct exynos5420_clock *clk =
955 (struct exynos5420_clock *)samsung_get_base_clock();
956 unsigned int addr;
Inha Songe25bfec2014-02-06 14:20:12 +0900957 unsigned int shift;
Rajeshwari Birje060c2272013-12-26 09:44:21 +0530958
959 /*
960 * CLK_DIV_FSYS1
961 * MMC0_RATIO [9:0]
962 * MMC1_RATIO [19:10]
963 * MMC2_RATIO [29:20]
964 */
965 addr = (unsigned int)&clk->div_fsys1;
966 shift = dev_index * 10;
967
Inha Songe25bfec2014-02-06 14:20:12 +0900968 clrsetbits_le32(addr, 0x3ff << shift, (div & 0x3ff) << shift);
Rajeshwari Birje060c2272013-12-26 09:44:21 +0530969}
970
Donghwa Lee37835d42012-04-05 19:36:12 +0000971/* get_lcd_clk: return lcd clock frequency */
972static unsigned long exynos4_get_lcd_clk(void)
973{
974 struct exynos4_clock *clk =
975 (struct exynos4_clock *)samsung_get_base_clock();
976 unsigned long pclk, sclk;
977 unsigned int sel;
978 unsigned int ratio;
979
980 /*
981 * CLK_SRC_LCD0
982 * FIMD0_SEL [3:0]
983 */
984 sel = readl(&clk->src_lcd0);
985 sel = sel & 0xf;
986
987 /*
988 * 0x6: SCLK_MPLL
989 * 0x7: SCLK_EPLL
990 * 0x8: SCLK_VPLL
991 */
992 if (sel == 0x6)
993 sclk = get_pll_clk(MPLL);
994 else if (sel == 0x7)
995 sclk = get_pll_clk(EPLL);
996 else if (sel == 0x8)
997 sclk = get_pll_clk(VPLL);
998 else
999 return 0;
1000
1001 /*
1002 * CLK_DIV_LCD0
1003 * FIMD0_RATIO [3:0]
1004 */
1005 ratio = readl(&clk->div_lcd0);
1006 ratio = ratio & 0xf;
1007
1008 pclk = sclk / (ratio + 1);
1009
1010 return pclk;
1011}
1012
Donghwa Lee2c5cd252012-07-02 01:15:49 +00001013/* get_lcd_clk: return lcd clock frequency */
1014static unsigned long exynos5_get_lcd_clk(void)
1015{
1016 struct exynos5_clock *clk =
1017 (struct exynos5_clock *)samsung_get_base_clock();
1018 unsigned long pclk, sclk;
1019 unsigned int sel;
1020 unsigned int ratio;
1021
1022 /*
1023 * CLK_SRC_LCD0
1024 * FIMD0_SEL [3:0]
1025 */
1026 sel = readl(&clk->src_disp1_0);
1027 sel = sel & 0xf;
1028
1029 /*
1030 * 0x6: SCLK_MPLL
1031 * 0x7: SCLK_EPLL
1032 * 0x8: SCLK_VPLL
1033 */
1034 if (sel == 0x6)
1035 sclk = get_pll_clk(MPLL);
1036 else if (sel == 0x7)
1037 sclk = get_pll_clk(EPLL);
1038 else if (sel == 0x8)
1039 sclk = get_pll_clk(VPLL);
1040 else
1041 return 0;
1042
1043 /*
1044 * CLK_DIV_LCD0
1045 * FIMD0_RATIO [3:0]
1046 */
1047 ratio = readl(&clk->div_disp1_0);
1048 ratio = ratio & 0xf;
1049
1050 pclk = sclk / (ratio + 1);
1051
1052 return pclk;
1053}
1054
Ajay Kumar496f0e42014-09-05 16:53:32 +05301055static unsigned long exynos5420_get_lcd_clk(void)
1056{
1057 struct exynos5420_clock *clk =
1058 (struct exynos5420_clock *)samsung_get_base_clock();
1059 unsigned long pclk, sclk;
1060 unsigned int sel;
1061 unsigned int ratio;
1062
1063 /*
1064 * CLK_SRC_DISP10
1065 * FIMD1_SEL [4]
1066 * 0: SCLK_RPLL
1067 * 1: SCLK_SPLL
1068 */
1069 sel = readl(&clk->src_disp10);
1070 sel &= (1 << 4);
1071
1072 if (sel)
1073 sclk = get_pll_clk(SPLL);
1074 else
1075 sclk = get_pll_clk(RPLL);
1076
1077 /*
1078 * CLK_DIV_DISP10
1079 * FIMD1_RATIO [3:0]
1080 */
1081 ratio = readl(&clk->div_disp10);
1082 ratio = ratio & 0xf;
1083
1084 pclk = sclk / (ratio + 1);
1085
1086 return pclk;
1087}
1088
Donghwa Lee37835d42012-04-05 19:36:12 +00001089void exynos4_set_lcd_clk(void)
1090{
1091 struct exynos4_clock *clk =
1092 (struct exynos4_clock *)samsung_get_base_clock();
Donghwa Lee37835d42012-04-05 19:36:12 +00001093
1094 /*
1095 * CLK_GATE_BLOCK
1096 * CLK_CAM [0]
1097 * CLK_TV [1]
1098 * CLK_MFC [2]
1099 * CLK_G3D [3]
1100 * CLK_LCD0 [4]
1101 * CLK_LCD1 [5]
1102 * CLK_GPS [7]
1103 */
Inha Songe25bfec2014-02-06 14:20:12 +09001104 setbits_le32(&clk->gate_block, 1 << 4);
Donghwa Lee37835d42012-04-05 19:36:12 +00001105
1106 /*
1107 * CLK_SRC_LCD0
1108 * FIMD0_SEL [3:0]
1109 * MDNIE0_SEL [7:4]
1110 * MDNIE_PWM0_SEL [8:11]
1111 * MIPI0_SEL [12:15]
1112 * set lcd0 src clock 0x6: SCLK_MPLL
1113 */
Inha Songe25bfec2014-02-06 14:20:12 +09001114 clrsetbits_le32(&clk->src_lcd0, 0xf, 0x6);
Donghwa Lee37835d42012-04-05 19:36:12 +00001115
1116 /*
1117 * CLK_GATE_IP_LCD0
1118 * CLK_FIMD0 [0]
1119 * CLK_MIE0 [1]
1120 * CLK_MDNIE0 [2]
1121 * CLK_DSIM0 [3]
1122 * CLK_SMMUFIMD0 [4]
1123 * CLK_PPMULCD0 [5]
1124 * Gating all clocks for FIMD0
1125 */
Inha Songe25bfec2014-02-06 14:20:12 +09001126 setbits_le32(&clk->gate_ip_lcd0, 1 << 0);
Donghwa Lee37835d42012-04-05 19:36:12 +00001127
1128 /*
1129 * CLK_DIV_LCD0
1130 * FIMD0_RATIO [3:0]
1131 * MDNIE0_RATIO [7:4]
1132 * MDNIE_PWM0_RATIO [11:8]
1133 * MDNIE_PWM_PRE_RATIO [15:12]
1134 * MIPI0_RATIO [19:16]
1135 * MIPI0_PRE_RATIO [23:20]
1136 * set fimd ratio
1137 */
Inha Songe25bfec2014-02-06 14:20:12 +09001138 clrsetbits_le32(&clk->div_lcd0, 0xf, 0x1);
Donghwa Lee37835d42012-04-05 19:36:12 +00001139}
1140
Donghwa Lee2c5cd252012-07-02 01:15:49 +00001141void exynos5_set_lcd_clk(void)
1142{
1143 struct exynos5_clock *clk =
1144 (struct exynos5_clock *)samsung_get_base_clock();
Donghwa Lee2c5cd252012-07-02 01:15:49 +00001145
1146 /*
1147 * CLK_GATE_BLOCK
1148 * CLK_CAM [0]
1149 * CLK_TV [1]
1150 * CLK_MFC [2]
1151 * CLK_G3D [3]
1152 * CLK_LCD0 [4]
1153 * CLK_LCD1 [5]
1154 * CLK_GPS [7]
1155 */
Inha Songe25bfec2014-02-06 14:20:12 +09001156 setbits_le32(&clk->gate_block, 1 << 4);
Donghwa Lee2c5cd252012-07-02 01:15:49 +00001157
1158 /*
1159 * CLK_SRC_LCD0
1160 * FIMD0_SEL [3:0]
1161 * MDNIE0_SEL [7:4]
1162 * MDNIE_PWM0_SEL [8:11]
1163 * MIPI0_SEL [12:15]
1164 * set lcd0 src clock 0x6: SCLK_MPLL
1165 */
Inha Songe25bfec2014-02-06 14:20:12 +09001166 clrsetbits_le32(&clk->src_disp1_0, 0xf, 0x6);
Donghwa Lee2c5cd252012-07-02 01:15:49 +00001167
1168 /*
1169 * CLK_GATE_IP_LCD0
1170 * CLK_FIMD0 [0]
1171 * CLK_MIE0 [1]
1172 * CLK_MDNIE0 [2]
1173 * CLK_DSIM0 [3]
1174 * CLK_SMMUFIMD0 [4]
1175 * CLK_PPMULCD0 [5]
1176 * Gating all clocks for FIMD0
1177 */
Inha Songe25bfec2014-02-06 14:20:12 +09001178 setbits_le32(&clk->gate_ip_disp1, 1 << 0);
Donghwa Lee2c5cd252012-07-02 01:15:49 +00001179
1180 /*
1181 * CLK_DIV_LCD0
1182 * FIMD0_RATIO [3:0]
1183 * MDNIE0_RATIO [7:4]
1184 * MDNIE_PWM0_RATIO [11:8]
1185 * MDNIE_PWM_PRE_RATIO [15:12]
1186 * MIPI0_RATIO [19:16]
1187 * MIPI0_PRE_RATIO [23:20]
1188 * set fimd ratio
1189 */
Inha Songe25bfec2014-02-06 14:20:12 +09001190 clrsetbits_le32(&clk->div_disp1_0, 0xf, 0x0);
Donghwa Lee2c5cd252012-07-02 01:15:49 +00001191}
1192
Ajay Kumar496f0e42014-09-05 16:53:32 +05301193void exynos5420_set_lcd_clk(void)
1194{
1195 struct exynos5420_clock *clk =
1196 (struct exynos5420_clock *)samsung_get_base_clock();
1197 unsigned int cfg;
1198
1199 /*
1200 * CLK_SRC_DISP10
1201 * FIMD1_SEL [4]
1202 * 0: SCLK_RPLL
1203 * 1: SCLK_SPLL
1204 */
1205 cfg = readl(&clk->src_disp10);
1206 cfg &= ~(0x1 << 4);
1207 cfg |= (0 << 4);
1208 writel(cfg, &clk->src_disp10);
1209
1210 /*
1211 * CLK_DIV_DISP10
1212 * FIMD1_RATIO [3:0]
1213 */
1214 cfg = readl(&clk->div_disp10);
1215 cfg &= ~(0xf << 0);
1216 cfg |= (0 << 0);
1217 writel(cfg, &clk->div_disp10);
1218}
1219
Donghwa Lee37835d42012-04-05 19:36:12 +00001220void exynos4_set_mipi_clk(void)
1221{
1222 struct exynos4_clock *clk =
1223 (struct exynos4_clock *)samsung_get_base_clock();
Donghwa Lee37835d42012-04-05 19:36:12 +00001224
1225 /*
1226 * CLK_SRC_LCD0
1227 * FIMD0_SEL [3:0]
1228 * MDNIE0_SEL [7:4]
1229 * MDNIE_PWM0_SEL [8:11]
1230 * MIPI0_SEL [12:15]
1231 * set mipi0 src clock 0x6: SCLK_MPLL
1232 */
Inha Songe25bfec2014-02-06 14:20:12 +09001233 clrsetbits_le32(&clk->src_lcd0, 0xf << 12, 0x6 << 12);
Donghwa Lee37835d42012-04-05 19:36:12 +00001234
1235 /*
1236 * CLK_SRC_MASK_LCD0
1237 * FIMD0_MASK [0]
1238 * MDNIE0_MASK [4]
1239 * MDNIE_PWM0_MASK [8]
1240 * MIPI0_MASK [12]
1241 * set src mask mipi0 0x1: Unmask
1242 */
Inha Songe25bfec2014-02-06 14:20:12 +09001243 setbits_le32(&clk->src_mask_lcd0, 0x1 << 12);
Donghwa Lee37835d42012-04-05 19:36:12 +00001244
1245 /*
1246 * CLK_GATE_IP_LCD0
1247 * CLK_FIMD0 [0]
1248 * CLK_MIE0 [1]
1249 * CLK_MDNIE0 [2]
1250 * CLK_DSIM0 [3]
1251 * CLK_SMMUFIMD0 [4]
1252 * CLK_PPMULCD0 [5]
1253 * Gating all clocks for MIPI0
1254 */
Inha Songe25bfec2014-02-06 14:20:12 +09001255 setbits_le32(&clk->gate_ip_lcd0, 1 << 3);
Donghwa Lee37835d42012-04-05 19:36:12 +00001256
1257 /*
1258 * CLK_DIV_LCD0
1259 * FIMD0_RATIO [3:0]
1260 * MDNIE0_RATIO [7:4]
1261 * MDNIE_PWM0_RATIO [11:8]
1262 * MDNIE_PWM_PRE_RATIO [15:12]
1263 * MIPI0_RATIO [19:16]
1264 * MIPI0_PRE_RATIO [23:20]
1265 * set mipi ratio
1266 */
Inha Songe25bfec2014-02-06 14:20:12 +09001267 clrsetbits_le32(&clk->div_lcd0, 0xf << 16, 0x1 << 16);
Donghwa Lee37835d42012-04-05 19:36:12 +00001268}
1269
Rajeshwari Shinde989feb82012-07-23 21:23:48 +00001270/*
1271 * I2C
1272 *
1273 * exynos5: obtaining the I2C clock
1274 */
1275static unsigned long exynos5_get_i2c_clk(void)
1276{
1277 struct exynos5_clock *clk =
1278 (struct exynos5_clock *)samsung_get_base_clock();
1279 unsigned long aclk_66, aclk_66_pre, sclk;
1280 unsigned int ratio;
1281
1282 sclk = get_pll_clk(MPLL);
1283
1284 ratio = (readl(&clk->div_top1)) >> 24;
1285 ratio &= 0x7;
1286 aclk_66_pre = sclk / (ratio + 1);
1287 ratio = readl(&clk->div_top0);
1288 ratio &= 0x7;
1289 aclk_66 = aclk_66_pre / (ratio + 1);
1290 return aclk_66;
1291}
1292
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001293int exynos5_set_epll_clk(unsigned long rate)
1294{
1295 unsigned int epll_con, epll_con_k;
1296 unsigned int i;
1297 unsigned int lockcnt;
1298 unsigned int start;
1299 struct exynos5_clock *clk =
1300 (struct exynos5_clock *)samsung_get_base_clock();
1301
1302 epll_con = readl(&clk->epll_con0);
1303 epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
1304 EPLL_CON0_LOCK_DET_EN_SHIFT) |
1305 EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
1306 EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
1307 EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
1308
1309 for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) {
1310 if (exynos5_epll_div[i].freq_out == rate)
1311 break;
1312 }
1313
1314 if (i == ARRAY_SIZE(exynos5_epll_div))
1315 return -1;
1316
1317 epll_con_k = exynos5_epll_div[i].k_dsm << 0;
1318 epll_con |= exynos5_epll_div[i].en_lock_det <<
1319 EPLL_CON0_LOCK_DET_EN_SHIFT;
1320 epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
1321 epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
1322 epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
1323
1324 /*
1325 * Required period ( in cycles) to genarate a stable clock output.
1326 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
1327 * frequency input (as per spec)
1328 */
1329 lockcnt = 3000 * exynos5_epll_div[i].p_div;
1330
1331 writel(lockcnt, &clk->epll_lock);
1332 writel(epll_con, &clk->epll_con0);
1333 writel(epll_con_k, &clk->epll_con1);
1334
1335 start = get_timer(0);
1336
1337 while (!(readl(&clk->epll_con0) &
1338 (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
1339 if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
1340 debug("%s: Timeout waiting for EPLL lock\n", __func__);
1341 return -1;
1342 }
1343 }
1344 return 0;
1345}
1346
Dani Krishna Mohan3dd22a32013-09-11 16:38:48 +05301347int exynos5_set_i2s_clk_source(unsigned int i2s_id)
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001348{
1349 struct exynos5_clock *clk =
1350 (struct exynos5_clock *)samsung_get_base_clock();
Dani Krishna Mohan3dd22a32013-09-11 16:38:48 +05301351 unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass();
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001352
Dani Krishna Mohan3dd22a32013-09-11 16:38:48 +05301353 if (i2s_id == 0) {
1354 setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL);
1355 clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK,
1356 (CLK_SRC_SCLK_EPLL));
1357 setbits_le32(audio_ass, AUDIO_CLKMUX_ASS);
1358 } else if (i2s_id == 1) {
1359 clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
1360 (CLK_SRC_SCLK_EPLL));
1361 } else {
1362 return -1;
1363 }
1364 return 0;
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001365}
1366
1367int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
Dani Krishna Mohan3dd22a32013-09-11 16:38:48 +05301368 unsigned int dst_frq,
1369 unsigned int i2s_id)
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001370{
1371 struct exynos5_clock *clk =
1372 (struct exynos5_clock *)samsung_get_base_clock();
1373 unsigned int div;
1374
1375 if ((dst_frq == 0) || (src_frq == 0)) {
1376 debug("%s: Invalid requency input for prescaler\n", __func__);
1377 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1378 return -1;
1379 }
1380
1381 div = (src_frq / dst_frq);
Dani Krishna Mohan3dd22a32013-09-11 16:38:48 +05301382 if (i2s_id == 0) {
1383 if (div > AUDIO_0_RATIO_MASK) {
1384 debug("%s: Frequency ratio is out of range\n",
1385 __func__);
1386 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1387 return -1;
1388 }
1389 clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK,
1390 (div & AUDIO_0_RATIO_MASK));
1391 } else if(i2s_id == 1) {
1392 if (div > AUDIO_1_RATIO_MASK) {
1393 debug("%s: Frequency ratio is out of range\n",
1394 __func__);
1395 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1396 return -1;
1397 }
1398 clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
1399 (div & AUDIO_1_RATIO_MASK));
1400 } else {
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001401 return -1;
1402 }
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001403 return 0;
1404}
1405
Hatim RVb56b3042012-11-02 01:15:34 +00001406/**
1407 * Linearly searches for the most accurate main and fine stage clock scalars
1408 * (divisors) for a specified target frequency and scalar bit sizes by checking
1409 * all multiples of main_scalar_bits values. Will always return scalars up to or
1410 * slower than target.
1411 *
1412 * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
1413 * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
1414 * @param input_freq Clock frequency to be scaled in Hz
1415 * @param target_freq Desired clock frequency in Hz
1416 * @param best_fine_scalar Pointer to store the fine stage divisor
1417 *
1418 * @return best_main_scalar Main scalar for desired frequency or -1 if none
1419 * found
1420 */
1421static int clock_calc_best_scalar(unsigned int main_scaler_bits,
1422 unsigned int fine_scalar_bits, unsigned int input_rate,
1423 unsigned int target_rate, unsigned int *best_fine_scalar)
1424{
1425 int i;
1426 int best_main_scalar = -1;
1427 unsigned int best_error = target_rate;
1428 const unsigned int cap = (1 << fine_scalar_bits) - 1;
1429 const unsigned int loops = 1 << main_scaler_bits;
1430
1431 debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
1432 target_rate, cap);
1433
1434 assert(best_fine_scalar != NULL);
1435 assert(main_scaler_bits <= fine_scalar_bits);
1436
1437 *best_fine_scalar = 1;
1438
1439 if (input_rate == 0 || target_rate == 0)
1440 return -1;
1441
1442 if (target_rate >= input_rate)
1443 return 1;
1444
1445 for (i = 1; i <= loops; i++) {
Masahiro Yamadab4141192014-11-07 03:03:31 +09001446 const unsigned int effective_div =
1447 max(min(input_rate / i / target_rate, cap), 1U);
Hatim RVb56b3042012-11-02 01:15:34 +00001448 const unsigned int effective_rate = input_rate / i /
1449 effective_div;
1450 const int error = target_rate - effective_rate;
1451
1452 debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
1453 effective_rate, error);
1454
1455 if (error >= 0 && error <= best_error) {
1456 best_error = error;
1457 best_main_scalar = i;
1458 *best_fine_scalar = effective_div;
1459 }
1460 }
1461
1462 return best_main_scalar;
1463}
1464
1465static int exynos5_set_spi_clk(enum periph_id periph_id,
1466 unsigned int rate)
1467{
1468 struct exynos5_clock *clk =
1469 (struct exynos5_clock *)samsung_get_base_clock();
1470 int main;
1471 unsigned int fine;
1472 unsigned shift, pre_shift;
1473 unsigned mask = 0xff;
1474 u32 *reg;
1475
1476 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1477 if (main < 0) {
1478 debug("%s: Cannot set clock rate for periph %d",
1479 __func__, periph_id);
1480 return -1;
1481 }
1482 main = main - 1;
1483 fine = fine - 1;
1484
1485 switch (periph_id) {
1486 case PERIPH_ID_SPI0:
1487 reg = &clk->div_peric1;
1488 shift = 0;
1489 pre_shift = 8;
1490 break;
1491 case PERIPH_ID_SPI1:
1492 reg = &clk->div_peric1;
1493 shift = 16;
1494 pre_shift = 24;
1495 break;
1496 case PERIPH_ID_SPI2:
1497 reg = &clk->div_peric2;
1498 shift = 0;
1499 pre_shift = 8;
1500 break;
1501 case PERIPH_ID_SPI3:
1502 reg = &clk->sclk_div_isp;
1503 shift = 0;
1504 pre_shift = 4;
1505 break;
1506 case PERIPH_ID_SPI4:
1507 reg = &clk->sclk_div_isp;
1508 shift = 12;
1509 pre_shift = 16;
1510 break;
1511 default:
1512 debug("%s: Unsupported peripheral ID %d\n", __func__,
1513 periph_id);
1514 return -1;
1515 }
1516 clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
1517 clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
1518
1519 return 0;
1520}
1521
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301522static int exynos5420_set_spi_clk(enum periph_id periph_id,
1523 unsigned int rate)
1524{
1525 struct exynos5420_clock *clk =
1526 (struct exynos5420_clock *)samsung_get_base_clock();
1527 int main;
1528 unsigned int fine;
1529 unsigned shift, pre_shift;
1530 unsigned div_mask = 0xf, pre_div_mask = 0xff;
1531 u32 *reg;
1532 u32 *pre_reg;
1533
1534 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1535 if (main < 0) {
1536 debug("%s: Cannot set clock rate for periph %d",
1537 __func__, periph_id);
1538 return -1;
1539 }
1540 main = main - 1;
1541 fine = fine - 1;
1542
1543 switch (periph_id) {
1544 case PERIPH_ID_SPI0:
1545 reg = &clk->div_peric1;
1546 shift = 20;
1547 pre_reg = &clk->div_peric4;
1548 pre_shift = 8;
1549 break;
1550 case PERIPH_ID_SPI1:
1551 reg = &clk->div_peric1;
1552 shift = 24;
1553 pre_reg = &clk->div_peric4;
1554 pre_shift = 16;
1555 break;
1556 case PERIPH_ID_SPI2:
1557 reg = &clk->div_peric1;
1558 shift = 28;
1559 pre_reg = &clk->div_peric4;
1560 pre_shift = 24;
1561 break;
1562 case PERIPH_ID_SPI3:
1563 reg = &clk->div_isp1;
1564 shift = 16;
1565 pre_reg = &clk->div_isp1;
1566 pre_shift = 0;
1567 break;
1568 case PERIPH_ID_SPI4:
1569 reg = &clk->div_isp1;
1570 shift = 20;
1571 pre_reg = &clk->div_isp1;
1572 pre_shift = 8;
1573 break;
1574 default:
1575 debug("%s: Unsupported peripheral ID %d\n", __func__,
1576 periph_id);
1577 return -1;
1578 }
1579
1580 clrsetbits_le32(reg, div_mask << shift, (main & div_mask) << shift);
1581 clrsetbits_le32(pre_reg, pre_div_mask << pre_shift,
1582 (fine & pre_div_mask) << pre_shift);
1583
1584 return 0;
1585}
1586
Piotr Wilczek83d745d2012-11-20 02:19:02 +00001587static unsigned long exynos4_get_i2c_clk(void)
1588{
1589 struct exynos4_clock *clk =
1590 (struct exynos4_clock *)samsung_get_base_clock();
1591 unsigned long sclk, aclk_100;
1592 unsigned int ratio;
1593
1594 sclk = get_pll_clk(APLL);
1595
1596 ratio = (readl(&clk->div_top)) >> 4;
1597 ratio &= 0xf;
1598 aclk_100 = sclk / (ratio + 1);
1599 return aclk_100;
Minkyu Kang008a3512011-01-24 15:22:23 +09001600}
1601
1602unsigned long get_pll_clk(int pllreg)
1603{
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301604 if (cpu_is_exynos5()) {
Akshay Saraswataa14b422014-11-13 22:38:15 +05301605 if (proid_is_exynos5420() || proid_is_exynos5800())
Akshay Saraswat325eb182015-02-04 16:00:00 +05301606 return exynos542x_get_pll_clk(pllreg);
Chander Kashyap37bb6d82012-02-05 23:01:46 +00001607 return exynos5_get_pll_clk(pllreg);
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301608 } else {
Chander Kashyapa5277572012-10-07 01:43:17 +00001609 if (proid_is_exynos4412())
1610 return exynos4x12_get_pll_clk(pllreg);
Chander Kashyap37bb6d82012-02-05 23:01:46 +00001611 return exynos4_get_pll_clk(pllreg);
Chander Kashyapa5277572012-10-07 01:43:17 +00001612 }
Minkyu Kang008a3512011-01-24 15:22:23 +09001613}
1614
1615unsigned long get_arm_clk(void)
1616{
Chander Kashyap37bb6d82012-02-05 23:01:46 +00001617 if (cpu_is_exynos5())
1618 return exynos5_get_arm_clk();
Chander Kashyapa5277572012-10-07 01:43:17 +00001619 else {
1620 if (proid_is_exynos4412())
1621 return exynos4x12_get_arm_clk();
Chander Kashyap37bb6d82012-02-05 23:01:46 +00001622 return exynos4_get_arm_clk();
Chander Kashyapa5277572012-10-07 01:43:17 +00001623 }
Minkyu Kang008a3512011-01-24 15:22:23 +09001624}
1625
Rajeshwari Shinde989feb82012-07-23 21:23:48 +00001626unsigned long get_i2c_clk(void)
1627{
1628 if (cpu_is_exynos5()) {
1629 return exynos5_get_i2c_clk();
Piotr Wilczek83d745d2012-11-20 02:19:02 +00001630 } else if (cpu_is_exynos4()) {
1631 return exynos4_get_i2c_clk();
Rajeshwari Shinde989feb82012-07-23 21:23:48 +00001632 } else {
1633 debug("I2C clock is not set for this CPU\n");
1634 return 0;
1635 }
1636}
1637
Minkyu Kang008a3512011-01-24 15:22:23 +09001638unsigned long get_pwm_clk(void)
1639{
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301640 if (cpu_is_exynos5()) {
Akshay Saraswataa14b422014-11-13 22:38:15 +05301641 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301642 return exynos5420_get_pwm_clk();
Padmavathi Vennae2338702013-03-28 04:32:23 +00001643 return clock_get_periph_rate(PERIPH_ID_PWM0);
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301644 } else {
Chander Kashyapa5277572012-10-07 01:43:17 +00001645 if (proid_is_exynos4412())
1646 return exynos4x12_get_pwm_clk();
Chander Kashyap37bb6d82012-02-05 23:01:46 +00001647 return exynos4_get_pwm_clk();
Chander Kashyapa5277572012-10-07 01:43:17 +00001648 }
Minkyu Kang008a3512011-01-24 15:22:23 +09001649}
1650
1651unsigned long get_uart_clk(int dev_index)
1652{
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301653 if (cpu_is_exynos5()) {
Akshay Saraswataa14b422014-11-13 22:38:15 +05301654 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301655 return exynos5420_get_uart_clk(dev_index);
Chander Kashyap37bb6d82012-02-05 23:01:46 +00001656 return exynos5_get_uart_clk(dev_index);
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301657 } else {
Chander Kashyapa5277572012-10-07 01:43:17 +00001658 if (proid_is_exynos4412())
1659 return exynos4x12_get_uart_clk(dev_index);
Chander Kashyap37bb6d82012-02-05 23:01:46 +00001660 return exynos4_get_uart_clk(dev_index);
Chander Kashyapa5277572012-10-07 01:43:17 +00001661 }
Minkyu Kang008a3512011-01-24 15:22:23 +09001662}
Jaehoon Chung68a8cbf2011-05-17 21:19:17 +00001663
Jaehoon Chungc39e9692012-12-27 22:30:32 +00001664unsigned long get_mmc_clk(int dev_index)
1665{
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301666 if (cpu_is_exynos5()) {
Akshay Saraswataa14b422014-11-13 22:38:15 +05301667 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301668 return exynos5420_get_mmc_clk(dev_index);
Jaehoon Chungc39e9692012-12-27 22:30:32 +00001669 return exynos5_get_mmc_clk(dev_index);
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301670 } else {
Jaehoon Chungc39e9692012-12-27 22:30:32 +00001671 return exynos4_get_mmc_clk(dev_index);
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301672 }
Jaehoon Chungc39e9692012-12-27 22:30:32 +00001673}
1674
Jaehoon Chung68a8cbf2011-05-17 21:19:17 +00001675void set_mmc_clk(int dev_index, unsigned int div)
1676{
Jaehoon Chunga2761722015-01-08 16:50:21 +09001677 /* If want to set correct value, it needs to substract one from div.*/
1678 if (div > 0)
1679 div -= 1;
1680
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301681 if (cpu_is_exynos5()) {
Akshay Saraswataa14b422014-11-13 22:38:15 +05301682 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301683 exynos5420_set_mmc_clk(dev_index, div);
1684 else
1685 exynos5_set_mmc_clk(dev_index, div);
1686 } else {
Beomho Seo00ee8132014-05-16 13:59:47 +09001687 exynos4_set_mmc_clk(dev_index, div);
Chander Kashyapa5277572012-10-07 01:43:17 +00001688 }
Jaehoon Chung68a8cbf2011-05-17 21:19:17 +00001689}
Donghwa Lee37835d42012-04-05 19:36:12 +00001690
1691unsigned long get_lcd_clk(void)
1692{
1693 if (cpu_is_exynos4())
1694 return exynos4_get_lcd_clk();
Ajay Kumar496f0e42014-09-05 16:53:32 +05301695 else {
Akshay Saraswataa14b422014-11-13 22:38:15 +05301696 if (proid_is_exynos5420() || proid_is_exynos5800())
Ajay Kumar496f0e42014-09-05 16:53:32 +05301697 return exynos5420_get_lcd_clk();
1698 else
1699 return exynos5_get_lcd_clk();
1700 }
Donghwa Lee37835d42012-04-05 19:36:12 +00001701}
1702
1703void set_lcd_clk(void)
1704{
1705 if (cpu_is_exynos4())
1706 exynos4_set_lcd_clk();
Ajay Kumar496f0e42014-09-05 16:53:32 +05301707 else {
1708 if (proid_is_exynos5250())
1709 exynos5_set_lcd_clk();
Akshay Saraswataa14b422014-11-13 22:38:15 +05301710 else if (proid_is_exynos5420() || proid_is_exynos5800())
Ajay Kumar496f0e42014-09-05 16:53:32 +05301711 exynos5420_set_lcd_clk();
1712 }
Donghwa Lee37835d42012-04-05 19:36:12 +00001713}
1714
1715void set_mipi_clk(void)
1716{
1717 if (cpu_is_exynos4())
1718 exynos4_set_mipi_clk();
1719}
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001720
Hatim RVb56b3042012-11-02 01:15:34 +00001721int set_spi_clk(int periph_id, unsigned int rate)
1722{
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301723 if (cpu_is_exynos5()) {
Akshay Saraswataa14b422014-11-13 22:38:15 +05301724 if (proid_is_exynos5420() || proid_is_exynos5800())
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301725 return exynos5420_set_spi_clk(periph_id, rate);
Hatim RVb56b3042012-11-02 01:15:34 +00001726 return exynos5_set_spi_clk(periph_id, rate);
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301727 } else {
Hatim RVb56b3042012-11-02 01:15:34 +00001728 return 0;
Rajeshwari Birje060c2272013-12-26 09:44:21 +05301729 }
Hatim RVb56b3042012-11-02 01:15:34 +00001730}
1731
Dani Krishna Mohan3dd22a32013-09-11 16:38:48 +05301732int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
1733 unsigned int i2s_id)
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001734{
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001735 if (cpu_is_exynos5())
Dani Krishna Mohan3dd22a32013-09-11 16:38:48 +05301736 return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id);
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001737 else
1738 return 0;
1739}
1740
Dani Krishna Mohan3dd22a32013-09-11 16:38:48 +05301741int set_i2s_clk_source(unsigned int i2s_id)
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001742{
1743 if (cpu_is_exynos5())
Dani Krishna Mohan3dd22a32013-09-11 16:38:48 +05301744 return exynos5_set_i2s_clk_source(i2s_id);
1745 else
1746 return 0;
Rajeshwari Shinde2e206ca2012-10-25 19:49:29 +00001747}
1748
1749int set_epll_clk(unsigned long rate)
1750{
1751 if (cpu_is_exynos5())
1752 return exynos5_set_epll_clk(rate);
1753 else
1754 return 0;
1755}