Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
[cascardo/linux.git] / arch / arm / mach-shmobile / clock-r8a7778.c
1 /*
2  * r8a7778 clock framework support
3  *
4  * Copyright (C) 2013  Renesas Solutions Corp.
5  * Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6  *
7  * based on r8a7779
8  *
9  * Copyright (C) 2011  Renesas Solutions Corp.
10  * Copyright (C) 2011  Magnus Damm
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26 /*
27  *     MD      MD      MD      MD       PLLA   PLLB    EXTAL   clki    clkz
28  *     19      18      12      11                      (HMz)   (MHz)   (MHz)
29  *----------------------------------------------------------------------------
30  *     1       0       0       0       x21     x21     38.00   800     800
31  *     1       0       0       1       x24     x24     33.33   800     800
32  *     1       0       1       0       x28     x28     28.50   800     800
33  *     1       0       1       1       x32     x32     25.00   800     800
34  *     1       1       0       1       x24     x21     33.33   800     700
35  *     1       1       1       0       x28     x21     28.50   800     600
36  *     1       1       1       1       x32     x24     25.00   800     600
37  */
38
39 #include <linux/io.h>
40 #include <linux/sh_clk.h>
41 #include <linux/clkdev.h>
42 #include <mach/clock.h>
43 #include <mach/common.h>
44
45 #define MSTPCR0         IOMEM(0xffc80030)
46 #define MSTPCR1         IOMEM(0xffc80034)
47 #define MSTPCR3         IOMEM(0xffc8003c)
48 #define MSTPSR1         IOMEM(0xffc80044)
49 #define MSTPSR4         IOMEM(0xffc80048)
50 #define MSTPSR6         IOMEM(0xffc8004c)
51 #define MSTPCR4         IOMEM(0xffc80050)
52 #define MSTPCR5         IOMEM(0xffc80054)
53 #define MSTPCR6         IOMEM(0xffc80058)
54 #define MODEMR          0xFFCC0020
55
56 #define MD(nr)  BIT(nr)
57
58 /* ioremap() through clock mapping mandatory to avoid
59  * collision with ARM coherent DMA virtual memory range.
60  */
61
62 static struct clk_mapping cpg_mapping = {
63         .phys   = 0xffc80000,
64         .len    = 0x80,
65 };
66
67 static struct clk extal_clk = {
68         /* .rate will be updated on r8a7778_clock_init() */
69         .mapping = &cpg_mapping,
70 };
71
72 /*
73  * clock ratio of these clock will be updated
74  * on r8a7778_clock_init()
75  */
76 SH_FIXED_RATIO_CLK_SET(plla_clk,        extal_clk, 1, 1);
77 SH_FIXED_RATIO_CLK_SET(pllb_clk,        extal_clk, 1, 1);
78 SH_FIXED_RATIO_CLK_SET(i_clk,           plla_clk,  1, 1);
79 SH_FIXED_RATIO_CLK_SET(s_clk,           plla_clk,  1, 1);
80 SH_FIXED_RATIO_CLK_SET(s1_clk,          plla_clk,  1, 1);
81 SH_FIXED_RATIO_CLK_SET(s3_clk,          plla_clk,  1, 1);
82 SH_FIXED_RATIO_CLK_SET(s4_clk,          plla_clk,  1, 1);
83 SH_FIXED_RATIO_CLK_SET(b_clk,           plla_clk,  1, 1);
84 SH_FIXED_RATIO_CLK_SET(out_clk,         plla_clk,  1, 1);
85 SH_FIXED_RATIO_CLK_SET(p_clk,           plla_clk,  1, 1);
86 SH_FIXED_RATIO_CLK_SET(g_clk,           plla_clk,  1, 1);
87 SH_FIXED_RATIO_CLK_SET(z_clk,           pllb_clk,  1, 1);
88
89 static struct clk *main_clks[] = {
90         &extal_clk,
91         &plla_clk,
92         &pllb_clk,
93         &i_clk,
94         &s_clk,
95         &s1_clk,
96         &s3_clk,
97         &s4_clk,
98         &b_clk,
99         &out_clk,
100         &p_clk,
101         &g_clk,
102         &z_clk,
103 };
104
105 enum {
106         MSTP331,
107         MSTP323, MSTP322, MSTP321,
108         MSTP114,
109         MSTP100,
110         MSTP030,
111         MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
112         MSTP016, MSTP015,
113         MSTP007,
114         MSTP_NR };
115
116 static struct clk mstp_clks[MSTP_NR] = {
117         [MSTP331] = SH_CLK_MSTP32(&s4_clk, MSTPCR3, 31, 0), /* MMC */
118         [MSTP323] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 23, 0), /* SDHI0 */
119         [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */
120         [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */
121         [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */
122         [MSTP100] = SH_CLK_MSTP32(&p_clk, MSTPCR1,  0, 0), /* USB0/1 */
123         [MSTP030] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 30, 0), /* I2C0 */
124         [MSTP029] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 29, 0), /* I2C1 */
125         [MSTP028] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 28, 0), /* I2C2 */
126         [MSTP027] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 27, 0), /* I2C3 */
127         [MSTP026] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 26, 0), /* SCIF0 */
128         [MSTP025] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 25, 0), /* SCIF1 */
129         [MSTP024] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 24, 0), /* SCIF2 */
130         [MSTP023] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 23, 0), /* SCIF3 */
131         [MSTP022] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 22, 0), /* SCIF4 */
132         [MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */
133         [MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */
134         [MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */
135         [MSTP007] = SH_CLK_MSTP32(&p_clk, MSTPCR0,  7, 0), /* HSPI */
136 };
137
138 static struct clk_lookup lookups[] = {
139         /* main */
140         CLKDEV_CON_ID("shyway_clk",     &s_clk),
141         CLKDEV_CON_ID("peripheral_clk", &p_clk),
142
143         /* MSTP32 clocks */
144         CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP331]), /* MMC */
145         CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
146         CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
147         CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
148         CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP114]), /* Ether */
149         CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
150         CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
151         CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
152         CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
153         CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
154         CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
155         CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
156         CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
157         CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
158         CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
159         CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
160         CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
161         CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
162         CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP015]), /* TMU01 */
163         CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
164         CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
165         CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
166 };
167
168 void __init r8a7778_clock_init(void)
169 {
170         void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
171         u32 mode;
172         int k, ret = 0;
173
174         BUG_ON(!modemr);
175         mode = ioread32(modemr);
176         iounmap(modemr);
177
178         switch (mode & (MD(19) | MD(18) | MD(12) | MD(11))) {
179         case MD(19):
180                 extal_clk.rate = 38000000;
181                 SH_CLK_SET_RATIO(&plla_clk_ratio,       21, 1);
182                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       21, 1);
183                 break;
184         case MD(19) | MD(11):
185                 extal_clk.rate = 33333333;
186                 SH_CLK_SET_RATIO(&plla_clk_ratio,       24, 1);
187                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       24, 1);
188                 break;
189         case MD(19) | MD(12):
190                 extal_clk.rate = 28500000;
191                 SH_CLK_SET_RATIO(&plla_clk_ratio,       28, 1);
192                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       28, 1);
193                 break;
194         case MD(19) | MD(12) | MD(11):
195                 extal_clk.rate = 25000000;
196                 SH_CLK_SET_RATIO(&plla_clk_ratio,       32, 1);
197                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       32, 1);
198                 break;
199         case MD(19) | MD(18) | MD(11):
200                 extal_clk.rate = 33333333;
201                 SH_CLK_SET_RATIO(&plla_clk_ratio,       24, 1);
202                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       21, 1);
203                 break;
204         case MD(19) | MD(18) | MD(12):
205                 extal_clk.rate = 28500000;
206                 SH_CLK_SET_RATIO(&plla_clk_ratio,       28, 1);
207                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       21, 1);
208                 break;
209         case MD(19) | MD(18) | MD(12) | MD(11):
210                 extal_clk.rate = 25000000;
211                 SH_CLK_SET_RATIO(&plla_clk_ratio,       32, 1);
212                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       24, 1);
213                 break;
214         default:
215                 BUG();
216         }
217
218         if (mode & MD(1)) {
219                 SH_CLK_SET_RATIO(&i_clk_ratio,  1, 1);
220                 SH_CLK_SET_RATIO(&s_clk_ratio,  1, 3);
221                 SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 6);
222                 SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4);
223                 SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8);
224                 SH_CLK_SET_RATIO(&p_clk_ratio,  1, 12);
225                 SH_CLK_SET_RATIO(&g_clk_ratio,  1, 12);
226                 if (mode & MD(2)) {
227                         SH_CLK_SET_RATIO(&b_clk_ratio,          1, 18);
228                         SH_CLK_SET_RATIO(&out_clk_ratio,        1, 18);
229                 } else {
230                         SH_CLK_SET_RATIO(&b_clk_ratio,          1, 12);
231                         SH_CLK_SET_RATIO(&out_clk_ratio,        1, 12);
232                 }
233         } else {
234                 SH_CLK_SET_RATIO(&i_clk_ratio,  1, 1);
235                 SH_CLK_SET_RATIO(&s_clk_ratio,  1, 4);
236                 SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 8);
237                 SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4);
238                 SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8);
239                 SH_CLK_SET_RATIO(&p_clk_ratio,  1, 16);
240                 SH_CLK_SET_RATIO(&g_clk_ratio,  1, 12);
241                 if (mode & MD(2)) {
242                         SH_CLK_SET_RATIO(&b_clk_ratio,          1, 16);
243                         SH_CLK_SET_RATIO(&out_clk_ratio,        1, 16);
244                 } else {
245                         SH_CLK_SET_RATIO(&b_clk_ratio,          1, 12);
246                         SH_CLK_SET_RATIO(&out_clk_ratio,        1, 12);
247                 }
248         }
249
250         for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
251                 ret = clk_register(main_clks[k]);
252
253         if (!ret)
254                 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
255
256         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
257
258         if (!ret)
259                 shmobile_clk_init();
260         else
261                 panic("failed to setup r8a7778 clocks\n");
262 }