Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
[linux-2.6-block.git] / arch / arm / mach-shmobile / clock-r8a7779.c
CommitLineData
f411fade
MD
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 */
ec0728d6 20#include <linux/bitops.h>
f411fade
MD
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>
ec0728d6 26#include <mach/clock.h>
f411fade
MD
27#include <mach/common.h>
28
f0ff5a0a
KM
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
ec0728d6
KM
48#define MD(nr) BIT(nr)
49
11f93576
KM
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)
f411fade 61
ec0728d6
KM
62#define MODEMR 0xffcc0020
63
64
f411fade
MD
65/* ioremap() through clock mapping mandatory to avoid
66 * collision with ARM coherent DMA virtual memory range.
67 */
68
69static struct clk_mapping cpg_mapping = {
70 .phys = 0xffc80000,
71 .len = 0x80,
72};
73
b5813c73
KM
74/*
75 * Default rate for the root input clock, reset this with clk_set_rate()
76 * from the platform code.
77 */
78static struct clk plla_clk = {
ec0728d6 79 /* .rate will be updated on r8a7779_clock_init() */
b5813c73 80 .mapping = &cpg_mapping,
f411fade
MD
81};
82
ec0728d6
KM
83/*
84 * clock ratio of these clock will be updated
85 * on r8a7779_clock_init()
86 */
87SH_FIXED_RATIO_CLK_SET(clkz_clk, plla_clk, 1, 1);
88SH_FIXED_RATIO_CLK_SET(clkzs_clk, plla_clk, 1, 1);
89SH_FIXED_RATIO_CLK_SET(clki_clk, plla_clk, 1, 1);
90SH_FIXED_RATIO_CLK_SET(clks_clk, plla_clk, 1, 1);
91SH_FIXED_RATIO_CLK_SET(clks1_clk, plla_clk, 1, 1);
92SH_FIXED_RATIO_CLK_SET(clks3_clk, plla_clk, 1, 1);
93SH_FIXED_RATIO_CLK_SET(clks4_clk, plla_clk, 1, 1);
94SH_FIXED_RATIO_CLK_SET(clkb_clk, plla_clk, 1, 1);
95SH_FIXED_RATIO_CLK_SET(clkout_clk, plla_clk, 1, 1);
96SH_FIXED_RATIO_CLK_SET(clkp_clk, plla_clk, 1, 1);
97SH_FIXED_RATIO_CLK_SET(clkg_clk, plla_clk, 1, 1);
98
f411fade 99static struct clk *main_clks[] = {
b5813c73 100 &plla_clk,
ec0728d6
KM
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,
f411fade
MD
112};
113
263510ec 114enum { MSTP323, MSTP322, MSTP321, MSTP320,
dace48d0 115 MSTP115, MSTP114,
d75bc78b 116 MSTP103, MSTP101, MSTP100,
16c40abc
KM
117 MSTP030,
118 MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
f411fade 119 MSTP016, MSTP015, MSTP014,
f92246e6 120 MSTP007,
f411fade
MD
121 MSTP_NR };
122
f411fade 123static struct clk mstp_clks[MSTP_NR] = {
ec0728d6
KM
124 [MSTP323] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 23, 0), /* SDHI0 */
125 [MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */
126 [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
127 [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
128 [MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */
dace48d0 129 [MSTP114] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 14, 0), /* Ether */
ec0728d6
KM
130 [MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 3, 0), /* DU */
131 [MSTP101] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 1, 0), /* USB2 */
132 [MSTP100] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 0, 0), /* USB0/1 */
133 [MSTP030] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 30, 0), /* I2C0 */
134 [MSTP029] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 29, 0), /* I2C1 */
135 [MSTP028] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 28, 0), /* I2C2 */
136 [MSTP027] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 27, 0), /* I2C3 */
137 [MSTP026] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 26, 0), /* SCIF0 */
138 [MSTP025] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 25, 0), /* SCIF1 */
139 [MSTP024] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 24, 0), /* SCIF2 */
140 [MSTP023] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 23, 0), /* SCIF3 */
141 [MSTP022] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 22, 0), /* SCIF4 */
142 [MSTP021] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 21, 0), /* SCIF5 */
143 [MSTP016] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 16, 0), /* TMU0 */
144 [MSTP015] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 15, 0), /* TMU1 */
145 [MSTP014] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 14, 0), /* TMU2 */
146 [MSTP007] = SH_CLK_MSTP32(&clks_clk, MSTPCR0, 7, 0), /* HSPI */
916b1f8c
KM
147};
148
f411fade 149static struct clk_lookup lookups[] = {
b5813c73
KM
150 /* main clocks */
151 CLKDEV_CON_ID("plla_clk", &plla_clk),
916b1f8c
KM
152 CLKDEV_CON_ID("clkz_clk", &clkz_clk),
153 CLKDEV_CON_ID("clkzs_clk", &clkzs_clk),
b5813c73
KM
154
155 /* DIV4 clocks */
ec0728d6
KM
156 CLKDEV_CON_ID("shyway_clk", &clks_clk),
157 CLKDEV_CON_ID("bus_clk", &clkout_clk),
158 CLKDEV_CON_ID("shyway4_clk", &clks4_clk),
159 CLKDEV_CON_ID("shyway3_clk", &clks3_clk),
160 CLKDEV_CON_ID("shyway1_clk", &clks1_clk),
161 CLKDEV_CON_ID("peripheral_clk", &clkp_clk),
b5813c73 162
f411fade 163 /* MSTP32 clocks */
a7b9837c
VB
164 CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
165 CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
dace48d0 166 CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP114]), /* Ether */
88419548 167 CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
9d69f5b8 168 CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
88419548 169 CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
9d69f5b8 170 CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
f411fade 171 CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
f9047306
SH
172 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */
173 CLKDEV_DEV_ID("sh_tmu.2", &mstp_clks[MSTP016]), /* TMU02 */
16c40abc
KM
174 CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
175 CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
176 CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
177 CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
f411fade
MD
178 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
179 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
180 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
181 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
182 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
183 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
f92246e6
KM
184 CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
185 CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
186 CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
263510ec
PE
187 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
188 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
189 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
190 CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */
d75bc78b 191 CLKDEV_DEV_ID("rcar-du.0", &mstp_clks[MSTP103]), /* DU */
f411fade
MD
192};
193
194void __init r8a7779_clock_init(void)
195{
ec0728d6
KM
196 void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
197 u32 mode;
f411fade
MD
198 int k, ret = 0;
199
ec0728d6
KM
200 BUG_ON(!modemr);
201 mode = ioread32(modemr);
202 iounmap(modemr);
203
204 if (mode & MD(1)) {
205 plla_clk.rate = 1500000000;
206
207 SH_CLK_SET_RATIO(&clkz_clk_ratio, 2, 3);
208 SH_CLK_SET_RATIO(&clkzs_clk_ratio, 1, 6);
209 SH_CLK_SET_RATIO(&clki_clk_ratio, 1, 2);
210 SH_CLK_SET_RATIO(&clks_clk_ratio, 1, 6);
211 SH_CLK_SET_RATIO(&clks1_clk_ratio, 1, 12);
212 SH_CLK_SET_RATIO(&clks3_clk_ratio, 1, 8);
213 SH_CLK_SET_RATIO(&clks4_clk_ratio, 1, 16);
214 SH_CLK_SET_RATIO(&clkp_clk_ratio, 1, 24);
215 SH_CLK_SET_RATIO(&clkg_clk_ratio, 1, 24);
216 if (mode & MD(2)) {
217 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 36);
218 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 36);
219 } else {
220 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 24);
221 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 24);
222 }
223 } else {
224 plla_clk.rate = 1600000000;
225
226 SH_CLK_SET_RATIO(&clkz_clk_ratio, 1, 2);
227 SH_CLK_SET_RATIO(&clkzs_clk_ratio, 1, 8);
228 SH_CLK_SET_RATIO(&clki_clk_ratio, 1, 2);
229 SH_CLK_SET_RATIO(&clks_clk_ratio, 1, 8);
230 SH_CLK_SET_RATIO(&clks1_clk_ratio, 1, 16);
231 SH_CLK_SET_RATIO(&clks3_clk_ratio, 1, 8);
232 SH_CLK_SET_RATIO(&clks4_clk_ratio, 1, 16);
233 SH_CLK_SET_RATIO(&clkp_clk_ratio, 1, 32);
234 SH_CLK_SET_RATIO(&clkg_clk_ratio, 1, 24);
235 if (mode & MD(2)) {
236 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 32);
237 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 32);
238 } else {
239 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 24);
240 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 24);
241 }
242 }
243
f411fade
MD
244 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
245 ret = clk_register(main_clks[k]);
246
247 if (!ret)
64e9de2f 248 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
f411fade
MD
249
250 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
251
252 if (!ret)
6b6a4c06 253 shmobile_clk_init();
f411fade
MD
254 else
255 panic("failed to setup r8a7779 clocks\n");
256}