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