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