Merge remote-tracking branch 'regulator/topic/tps65910' into regulator-next
[deliverable/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 MSTP110, MSTP109,
110 MSTP100,
111 MSTP030,
112 MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
113 MSTP016, MSTP015,
114 MSTP007,
115 MSTP_NR };
116
117 static struct clk mstp_clks[MSTP_NR] = {
118 [MSTP331] = SH_CLK_MSTP32(&s4_clk, MSTPCR3, 31, 0), /* MMC */
119 [MSTP323] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 23, 0), /* SDHI0 */
120 [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */
121 [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */
122 [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */
123 [MSTP110] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 10, 0), /* VIN0 */
124 [MSTP109] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 9, 0), /* VIN1 */
125 [MSTP100] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 0, 0), /* USB0/1 */
126 [MSTP030] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 30, 0), /* I2C0 */
127 [MSTP029] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 29, 0), /* I2C1 */
128 [MSTP028] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 28, 0), /* I2C2 */
129 [MSTP027] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 27, 0), /* I2C3 */
130 [MSTP026] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 26, 0), /* SCIF0 */
131 [MSTP025] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 25, 0), /* SCIF1 */
132 [MSTP024] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 24, 0), /* SCIF2 */
133 [MSTP023] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 23, 0), /* SCIF3 */
134 [MSTP022] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 22, 0), /* SCIF4 */
135 [MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */
136 [MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */
137 [MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */
138 [MSTP007] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 7, 0), /* HSPI */
139 };
140
141 static struct clk_lookup lookups[] = {
142 /* main */
143 CLKDEV_CON_ID("shyway_clk", &s_clk),
144 CLKDEV_CON_ID("peripheral_clk", &p_clk),
145
146 /* MSTP32 clocks */
147 CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP331]), /* MMC */
148 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
149 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
150 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
151 CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
152 CLKDEV_DEV_ID("r8a7778-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
153 CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
154 CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
155 CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
156 CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
157 CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
158 CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
159 CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
160 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
161 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
162 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
163 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
164 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
165 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
166 CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
167 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP015]), /* TMU01 */
168 CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
169 CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
170 CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
171 };
172
173 void __init r8a7778_clock_init(void)
174 {
175 void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
176 u32 mode;
177 int k, ret = 0;
178
179 BUG_ON(!modemr);
180 mode = ioread32(modemr);
181 iounmap(modemr);
182
183 switch (mode & (MD(19) | MD(18) | MD(12) | MD(11))) {
184 case MD(19):
185 extal_clk.rate = 38000000;
186 SH_CLK_SET_RATIO(&plla_clk_ratio, 21, 1);
187 SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1);
188 break;
189 case MD(19) | MD(11):
190 extal_clk.rate = 33333333;
191 SH_CLK_SET_RATIO(&plla_clk_ratio, 24, 1);
192 SH_CLK_SET_RATIO(&pllb_clk_ratio, 24, 1);
193 break;
194 case MD(19) | MD(12):
195 extal_clk.rate = 28500000;
196 SH_CLK_SET_RATIO(&plla_clk_ratio, 28, 1);
197 SH_CLK_SET_RATIO(&pllb_clk_ratio, 28, 1);
198 break;
199 case MD(19) | MD(12) | MD(11):
200 extal_clk.rate = 25000000;
201 SH_CLK_SET_RATIO(&plla_clk_ratio, 32, 1);
202 SH_CLK_SET_RATIO(&pllb_clk_ratio, 32, 1);
203 break;
204 case MD(19) | MD(18) | MD(11):
205 extal_clk.rate = 33333333;
206 SH_CLK_SET_RATIO(&plla_clk_ratio, 24, 1);
207 SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1);
208 break;
209 case MD(19) | MD(18) | MD(12):
210 extal_clk.rate = 28500000;
211 SH_CLK_SET_RATIO(&plla_clk_ratio, 28, 1);
212 SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1);
213 break;
214 case MD(19) | MD(18) | MD(12) | MD(11):
215 extal_clk.rate = 25000000;
216 SH_CLK_SET_RATIO(&plla_clk_ratio, 32, 1);
217 SH_CLK_SET_RATIO(&pllb_clk_ratio, 24, 1);
218 break;
219 default:
220 BUG();
221 }
222
223 if (mode & MD(1)) {
224 SH_CLK_SET_RATIO(&i_clk_ratio, 1, 1);
225 SH_CLK_SET_RATIO(&s_clk_ratio, 1, 3);
226 SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 6);
227 SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4);
228 SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8);
229 SH_CLK_SET_RATIO(&p_clk_ratio, 1, 12);
230 SH_CLK_SET_RATIO(&g_clk_ratio, 1, 12);
231 if (mode & MD(2)) {
232 SH_CLK_SET_RATIO(&b_clk_ratio, 1, 18);
233 SH_CLK_SET_RATIO(&out_clk_ratio, 1, 18);
234 } else {
235 SH_CLK_SET_RATIO(&b_clk_ratio, 1, 12);
236 SH_CLK_SET_RATIO(&out_clk_ratio, 1, 12);
237 }
238 } else {
239 SH_CLK_SET_RATIO(&i_clk_ratio, 1, 1);
240 SH_CLK_SET_RATIO(&s_clk_ratio, 1, 4);
241 SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 8);
242 SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4);
243 SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8);
244 SH_CLK_SET_RATIO(&p_clk_ratio, 1, 16);
245 SH_CLK_SET_RATIO(&g_clk_ratio, 1, 12);
246 if (mode & MD(2)) {
247 SH_CLK_SET_RATIO(&b_clk_ratio, 1, 16);
248 SH_CLK_SET_RATIO(&out_clk_ratio, 1, 16);
249 } else {
250 SH_CLK_SET_RATIO(&b_clk_ratio, 1, 12);
251 SH_CLK_SET_RATIO(&out_clk_ratio, 1, 12);
252 }
253 }
254
255 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
256 ret = clk_register(main_clks[k]);
257
258 if (!ret)
259 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
260
261 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
262
263 if (!ret)
264 shmobile_clk_init();
265 else
266 panic("failed to setup r8a7778 clocks\n");
267 }
This page took 0.043829 seconds and 5 git commands to generate.