]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - arch/arm/mach-shmobile/clock-r8a7791.c
Merge branch 'akpm' (incoming from Andrew)
[mirror_ubuntu-zesty-kernel.git] / arch / arm / mach-shmobile / clock-r8a7791.c
CommitLineData
0d0771ab
HN
1/*
2 * r8a7791 clock framework support
3 *
4 * Copyright (C) 2013 Renesas Electronics Corporation
5 * Copyright (C) 2013 Renesas Solutions Corp.
6 * Copyright (C) 2013 Magnus Damm
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21#include <linux/init.h>
22#include <linux/io.h>
23#include <linux/kernel.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 * MD EXTAL PLL0 PLL1 PLL3
31 * 14 13 19 (MHz) *1 *1
32 *---------------------------------------------------
33 * 0 0 0 15 x 1 x172/2 x208/2 x106
34 * 0 0 1 15 x 1 x172/2 x208/2 x88
35 * 0 1 0 20 x 1 x130/2 x156/2 x80
36 * 0 1 1 20 x 1 x130/2 x156/2 x66
37 * 1 0 0 26 / 2 x200/2 x240/2 x122
38 * 1 0 1 26 / 2 x200/2 x240/2 x102
39 * 1 1 0 30 / 2 x172/2 x208/2 x106
40 * 1 1 1 30 / 2 x172/2 x208/2 x88
41 *
42 * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2)
43 * see "p1 / 2" on R8A7791_CLOCK_ROOT() below
44 */
45
46#define MD(nr) (1 << nr)
47
48#define CPG_BASE 0xe6150000
49#define CPG_LEN 0x1000
50
e6491d08 51#define SMSTPCR0 0xE6150130
0d0771ab
HN
52#define SMSTPCR1 0xE6150134
53#define SMSTPCR2 0xe6150138
54#define SMSTPCR3 0xE615013C
55#define SMSTPCR5 0xE6150144
56#define SMSTPCR7 0xe615014c
57#define SMSTPCR8 0xE6150990
58#define SMSTPCR9 0xE6150994
59#define SMSTPCR10 0xE6150998
e6491d08 60#define SMSTPCR11 0xE615099C
0d0771ab
HN
61
62#define MODEMR 0xE6160060
63#define SDCKCR 0xE6150074
64#define SD2CKCR 0xE6150078
65#define SD3CKCR 0xE615007C
66#define MMC0CKCR 0xE6150240
67#define MMC1CKCR 0xE6150244
68#define SSPCKCR 0xE6150248
69#define SSPRSCKCR 0xE615024C
70
71static struct clk_mapping cpg_mapping = {
72 .phys = CPG_BASE,
73 .len = CPG_LEN,
74};
75
76static struct clk extal_clk = {
77 /* .rate will be updated on r8a7791_clock_init() */
78 .mapping = &cpg_mapping,
79};
80
81static struct sh_clk_ops followparent_clk_ops = {
82 .recalc = followparent_recalc,
83};
84
85static struct clk main_clk = {
86 /* .parent will be set r8a73a4_clock_init */
87 .ops = &followparent_clk_ops,
88};
89
90/*
91 * clock ratio of these clock will be updated
92 * on r8a7791_clock_init()
93 */
94SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1);
95SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1);
96
97/* fixed ratio clock */
98SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2);
99SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2);
100
101SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2);
102SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12);
103SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24);
1bebd72a 104SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024));
0d0771ab 105SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15);
cf4f85cc 106SH_FIXED_RATIO_CLK_SET(zx_clk, pll1_clk, 1, 3);
0d0771ab
HN
107
108static struct clk *main_clks[] = {
109 &extal_clk,
110 &extal_div2_clk,
111 &main_clk,
112 &pll1_clk,
113 &pll1_div2_clk,
114 &pll3_clk,
115 &hp_clk,
116 &p_clk,
1bebd72a 117 &rclk_clk,
0d0771ab
HN
118 &mp_clk,
119 &cp_clk,
cf4f85cc 120 &zx_clk,
0d0771ab
HN
121};
122
123/* MSTP */
124enum {
893c3f0b 125 MSTP813,
cf4f85cc 126 MSTP726, MSTP724, MSTP723, MSTP721, MSTP720,
e6491d08 127 MSTP719, MSTP718, MSTP715, MSTP714,
8476cee6 128 MSTP522,
e6491d08
YF
129 MSTP216, MSTP207, MSTP206,
130 MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107,
1bebd72a 131 MSTP124,
0d0771ab
HN
132 MSTP_NR
133};
134
135static struct clk mstp_clks[MSTP_NR] = {
893c3f0b 136 [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */
cf4f85cc
LP
137 [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */
138 [MSTP724] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 24, 0), /* DU0 */
139 [MSTP723] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 23, 0), /* DU1 */
0d0771ab
HN
140 [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */
141 [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */
e6491d08
YF
142 [MSTP719] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 19, 0), /* SCIF2 */
143 [MSTP718] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 18, 0), /* SCIF3 */
144 [MSTP715] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 15, 0), /* SCIF4 */
145 [MSTP714] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 14, 0), /* SCIF5 */
8476cee6 146 [MSTP522] = SH_CLK_MSTP32(&extal_clk, SMSTPCR5, 22, 0), /* Thermal */
e6491d08
YF
147 [MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */
148 [MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */
149 [MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */
150 [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */
151 [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */
152 [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */
153 [MSTP1105] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 5, 0), /* SCIFA3 */
154 [MSTP1106] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 6, 0), /* SCIFA4 */
155 [MSTP1107] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 7, 0), /* SCIFA5 */
1bebd72a 156 [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */
0d0771ab
HN
157};
158
159static struct clk_lookup lookups[] = {
160
161 /* main clocks */
162 CLKDEV_CON_ID("extal", &extal_clk),
163 CLKDEV_CON_ID("extal_div2", &extal_div2_clk),
164 CLKDEV_CON_ID("main", &main_clk),
165 CLKDEV_CON_ID("pll1", &pll1_clk),
166 CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk),
167 CLKDEV_CON_ID("pll3", &pll3_clk),
168 CLKDEV_CON_ID("hp", &hp_clk),
169 CLKDEV_CON_ID("p", &p_clk),
1bebd72a 170 CLKDEV_CON_ID("rclk", &rclk_clk),
0d0771ab
HN
171 CLKDEV_CON_ID("mp", &mp_clk),
172 CLKDEV_CON_ID("cp", &cp_clk),
173 CLKDEV_CON_ID("peripheral_clk", &hp_clk),
e6491d08
YF
174
175 /* MSTP */
cf4f85cc
LP
176 CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7791", &mstp_clks[MSTP726]),
177 CLKDEV_ICK_ID("du.0", "rcar-du-r8a7791", &mstp_clks[MSTP724]),
178 CLKDEV_ICK_ID("du.1", "rcar-du-r8a7791", &mstp_clks[MSTP723]),
e6491d08
YF
179 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
180 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
181 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), /* SCIFB0 */
182 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), /* SCIFB1 */
183 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), /* SCIFB2 */
184 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]), /* SCIFA2 */
185 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]), /* SCIF0 */
186 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), /* SCIF1 */
187 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP719]), /* SCIF2 */
188 CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */
189 CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */
190 CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */
191 CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */
192 CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */
193 CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */
1bebd72a 194 CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
8476cee6
MD
195 CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]),
196 CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
893c3f0b 197 CLKDEV_DEV_ID("r8a7791-ether", &mstp_clks[MSTP813]), /* Ether */
0d0771ab
HN
198};
199
200#define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \
201 extal_clk.rate = e * 1000 * 1000; \
202 main_clk.parent = m; \
203 SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \
204 if (mode & MD(19)) \
205 SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \
206 else \
207 SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1)
208
209
210void __init r8a7791_clock_init(void)
211{
212 void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
213 u32 mode;
214 int k, ret = 0;
215
216 BUG_ON(!modemr);
217 mode = ioread32(modemr);
218 iounmap(modemr);
219
220 switch (mode & (MD(14) | MD(13))) {
221 case 0:
222 R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
223 break;
224 case MD(13):
225 R8A7791_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66);
226 break;
227 case MD(14):
228 R8A7791_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102);
229 break;
230 case MD(13) | MD(14):
231 R8A7791_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88);
232 break;
233 }
234
235 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
236 ret = clk_register(main_clks[k]);
237
238 if (!ret)
239 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
240
241 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
242
243 if (!ret)
244 shmobile_clk_init();
245 else
246 goto epanic;
247
248 return;
249
250epanic:
251 panic("failed to setup r8a7791 clocks\n");
252}