ARM: shmobile: r8a7779: add SDHI clock support for DT
[deliverable/linux.git] / arch / arm / mach-shmobile / clock-r8a7779.c
1 /*
2 * r8a7779 clock framework support
3 *
4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Copyright (C) 2011 Magnus Damm
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 #include <linux/bitops.h>
21 #include <linux/init.h>
22 #include <linux/kernel.h>
23 #include <linux/io.h>
24 #include <linux/sh_clk.h>
25 #include <linux/clkdev.h>
26 #include <mach/clock.h>
27 #include <mach/common.h>
28
29 /*
30 * MD1 = 1 MD1 = 0
31 * (PLLA = 1500) (PLLA = 1600)
32 * (MHz) (MHz)
33 *------------------------------------------------+--------------------
34 * clkz 1000 (2/3) 800 (1/2)
35 * clkzs 250 (1/6) 200 (1/8)
36 * clki 750 (1/2) 800 (1/2)
37 * clks 250 (1/6) 200 (1/8)
38 * clks1 125 (1/12) 100 (1/16)
39 * clks3 187.5 (1/8) 200 (1/8)
40 * clks4 93.7 (1/16) 100 (1/16)
41 * clkp 62.5 (1/24) 50 (1/32)
42 * clkg 62.5 (1/24) 66.6 (1/24)
43 * clkb, CLKOUT
44 * (MD2 = 0) 62.5 (1/24) 66.6 (1/24)
45 * (MD2 = 1) 41.6 (1/36) 50 (1/32)
46 */
47
48 #define MD(nr) BIT(nr)
49
50 #define FRQMR IOMEM(0xffc80014)
51 #define MSTPCR0 IOMEM(0xffc80030)
52 #define MSTPCR1 IOMEM(0xffc80034)
53 #define MSTPCR3 IOMEM(0xffc8003c)
54 #define MSTPSR1 IOMEM(0xffc80044)
55 #define MSTPSR4 IOMEM(0xffc80048)
56 #define MSTPSR6 IOMEM(0xffc8004c)
57 #define MSTPCR4 IOMEM(0xffc80050)
58 #define MSTPCR5 IOMEM(0xffc80054)
59 #define MSTPCR6 IOMEM(0xffc80058)
60 #define MSTPCR7 IOMEM(0xffc80040)
61
62 #define MODEMR 0xffcc0020
63
64
65 /* ioremap() through clock mapping mandatory to avoid
66 * collision with ARM coherent DMA virtual memory range.
67 */
68
69 static struct clk_mapping cpg_mapping = {
70 .phys = 0xffc80000,
71 .len = 0x80,
72 };
73
74 /*
75 * Default rate for the root input clock, reset this with clk_set_rate()
76 * from the platform code.
77 */
78 static struct clk plla_clk = {
79 /* .rate will be updated on r8a7779_clock_init() */
80 .mapping = &cpg_mapping,
81 };
82
83 /*
84 * clock ratio of these clock will be updated
85 * on r8a7779_clock_init()
86 */
87 SH_FIXED_RATIO_CLK_SET(clkz_clk, plla_clk, 1, 1);
88 SH_FIXED_RATIO_CLK_SET(clkzs_clk, plla_clk, 1, 1);
89 SH_FIXED_RATIO_CLK_SET(clki_clk, plla_clk, 1, 1);
90 SH_FIXED_RATIO_CLK_SET(clks_clk, plla_clk, 1, 1);
91 SH_FIXED_RATIO_CLK_SET(clks1_clk, plla_clk, 1, 1);
92 SH_FIXED_RATIO_CLK_SET(clks3_clk, plla_clk, 1, 1);
93 SH_FIXED_RATIO_CLK_SET(clks4_clk, plla_clk, 1, 1);
94 SH_FIXED_RATIO_CLK_SET(clkb_clk, plla_clk, 1, 1);
95 SH_FIXED_RATIO_CLK_SET(clkout_clk, plla_clk, 1, 1);
96 SH_FIXED_RATIO_CLK_SET(clkp_clk, plla_clk, 1, 1);
97 SH_FIXED_RATIO_CLK_SET(clkg_clk, plla_clk, 1, 1);
98
99 static struct clk *main_clks[] = {
100 &plla_clk,
101 &clkz_clk,
102 &clkzs_clk,
103 &clki_clk,
104 &clks_clk,
105 &clks1_clk,
106 &clks3_clk,
107 &clks4_clk,
108 &clkb_clk,
109 &clkout_clk,
110 &clkp_clk,
111 &clkg_clk,
112 };
113
114 enum { MSTP323, MSTP322, MSTP321, MSTP320,
115 MSTP120,
116 MSTP116, MSTP115, MSTP114,
117 MSTP110, MSTP109, MSTP108,
118 MSTP103, MSTP101, MSTP100,
119 MSTP030,
120 MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
121 MSTP016, MSTP015, MSTP014,
122 MSTP007,
123 MSTP_NR };
124
125 static struct clk mstp_clks[MSTP_NR] = {
126 [MSTP323] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 23, 0), /* SDHI0 */
127 [MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */
128 [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
129 [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
130 [MSTP120] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 20, 0), /* VIN3 */
131 [MSTP116] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 16, 0), /* PCIe */
132 [MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */
133 [MSTP114] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 14, 0), /* Ether */
134 [MSTP110] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 10, 0), /* VIN0 */
135 [MSTP109] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 9, 0), /* VIN1 */
136 [MSTP108] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 8, 0), /* VIN2 */
137 [MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 3, 0), /* DU */
138 [MSTP101] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 1, 0), /* USB2 */
139 [MSTP100] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 0, 0), /* USB0/1 */
140 [MSTP030] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 30, 0), /* I2C0 */
141 [MSTP029] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 29, 0), /* I2C1 */
142 [MSTP028] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 28, 0), /* I2C2 */
143 [MSTP027] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 27, 0), /* I2C3 */
144 [MSTP026] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 26, 0), /* SCIF0 */
145 [MSTP025] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 25, 0), /* SCIF1 */
146 [MSTP024] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 24, 0), /* SCIF2 */
147 [MSTP023] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 23, 0), /* SCIF3 */
148 [MSTP022] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 22, 0), /* SCIF4 */
149 [MSTP021] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 21, 0), /* SCIF5 */
150 [MSTP016] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 16, 0), /* TMU0 */
151 [MSTP015] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 15, 0), /* TMU1 */
152 [MSTP014] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 14, 0), /* TMU2 */
153 [MSTP007] = SH_CLK_MSTP32(&clks_clk, MSTPCR0, 7, 0), /* HSPI */
154 };
155
156 static struct clk_lookup lookups[] = {
157 /* main clocks */
158 CLKDEV_CON_ID("plla_clk", &plla_clk),
159 CLKDEV_CON_ID("clkz_clk", &clkz_clk),
160 CLKDEV_CON_ID("clkzs_clk", &clkzs_clk),
161
162 /* DIV4 clocks */
163 CLKDEV_CON_ID("shyway_clk", &clks_clk),
164 CLKDEV_CON_ID("bus_clk", &clkout_clk),
165 CLKDEV_CON_ID("shyway4_clk", &clks4_clk),
166 CLKDEV_CON_ID("shyway3_clk", &clks3_clk),
167 CLKDEV_CON_ID("shyway1_clk", &clks1_clk),
168 CLKDEV_CON_ID("peripheral_clk", &clkp_clk),
169
170 /* MSTP32 clocks */
171 CLKDEV_DEV_ID("r8a7779-vin.3", &mstp_clks[MSTP120]), /* VIN3 */
172 CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */
173 CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
174 CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
175 CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
176 CLKDEV_DEV_ID("r8a7779-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
177 CLKDEV_DEV_ID("r8a7779-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
178 CLKDEV_DEV_ID("r8a7779-vin.2", &mstp_clks[MSTP108]), /* VIN2 */
179 CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
180 CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
181 CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
182 CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
183 CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
184 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */
185 CLKDEV_DEV_ID("sh_tmu.2", &mstp_clks[MSTP016]), /* TMU02 */
186 CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
187 CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
188 CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
189 CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
190 CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
191 CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
192 CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
193 CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
194 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
195 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
196 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
197 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
198 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
199 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
200 CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
201 CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
202 CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
203 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
204 CLKDEV_DEV_ID("ffe4c000.sdhi", &mstp_clks[MSTP323]), /* SDHI0 */
205 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
206 CLKDEV_DEV_ID("ffe4d000.sdhi", &mstp_clks[MSTP322]), /* SDHI1 */
207 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
208 CLKDEV_DEV_ID("ffe4e000.sdhi", &mstp_clks[MSTP321]), /* SDHI2 */
209 CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */
210 CLKDEV_DEV_ID("ffe4f000.sdhi", &mstp_clks[MSTP320]), /* SDHI3 */
211 CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */
212 };
213
214 void __init r8a7779_clock_init(void)
215 {
216 void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
217 u32 mode;
218 int k, ret = 0;
219
220 BUG_ON(!modemr);
221 mode = ioread32(modemr);
222 iounmap(modemr);
223
224 if (mode & MD(1)) {
225 plla_clk.rate = 1500000000;
226
227 SH_CLK_SET_RATIO(&clkz_clk_ratio, 2, 3);
228 SH_CLK_SET_RATIO(&clkzs_clk_ratio, 1, 6);
229 SH_CLK_SET_RATIO(&clki_clk_ratio, 1, 2);
230 SH_CLK_SET_RATIO(&clks_clk_ratio, 1, 6);
231 SH_CLK_SET_RATIO(&clks1_clk_ratio, 1, 12);
232 SH_CLK_SET_RATIO(&clks3_clk_ratio, 1, 8);
233 SH_CLK_SET_RATIO(&clks4_clk_ratio, 1, 16);
234 SH_CLK_SET_RATIO(&clkp_clk_ratio, 1, 24);
235 SH_CLK_SET_RATIO(&clkg_clk_ratio, 1, 24);
236 if (mode & MD(2)) {
237 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 36);
238 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 36);
239 } else {
240 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 24);
241 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 24);
242 }
243 } else {
244 plla_clk.rate = 1600000000;
245
246 SH_CLK_SET_RATIO(&clkz_clk_ratio, 1, 2);
247 SH_CLK_SET_RATIO(&clkzs_clk_ratio, 1, 8);
248 SH_CLK_SET_RATIO(&clki_clk_ratio, 1, 2);
249 SH_CLK_SET_RATIO(&clks_clk_ratio, 1, 8);
250 SH_CLK_SET_RATIO(&clks1_clk_ratio, 1, 16);
251 SH_CLK_SET_RATIO(&clks3_clk_ratio, 1, 8);
252 SH_CLK_SET_RATIO(&clks4_clk_ratio, 1, 16);
253 SH_CLK_SET_RATIO(&clkp_clk_ratio, 1, 32);
254 SH_CLK_SET_RATIO(&clkg_clk_ratio, 1, 24);
255 if (mode & MD(2)) {
256 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 32);
257 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 32);
258 } else {
259 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 24);
260 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 24);
261 }
262 }
263
264 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
265 ret = clk_register(main_clks[k]);
266
267 if (!ret)
268 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
269
270 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
271
272 if (!ret)
273 shmobile_clk_init();
274 else
275 panic("failed to setup r8a7779 clocks\n");
276 }
This page took 0.038173 seconds and 5 git commands to generate.