• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "clock.h"
43 #include "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 static struct clk audio_clk_a = {
73 };
74 
75 static struct clk audio_clk_b = {
76 };
77 
78 static struct clk audio_clk_c = {
79 };
80 
81 /*
82  * clock ratio of these clock will be updated
83  * on r8a7778_clock_init()
84  */
85 SH_FIXED_RATIO_CLK_SET(plla_clk,	extal_clk, 1, 1);
86 SH_FIXED_RATIO_CLK_SET(pllb_clk,	extal_clk, 1, 1);
87 SH_FIXED_RATIO_CLK_SET(i_clk,		plla_clk,  1, 1);
88 SH_FIXED_RATIO_CLK_SET(s_clk,		plla_clk,  1, 1);
89 SH_FIXED_RATIO_CLK_SET(s1_clk,		plla_clk,  1, 1);
90 SH_FIXED_RATIO_CLK_SET(s3_clk,		plla_clk,  1, 1);
91 SH_FIXED_RATIO_CLK_SET(s4_clk,		plla_clk,  1, 1);
92 SH_FIXED_RATIO_CLK_SET(b_clk,		plla_clk,  1, 1);
93 SH_FIXED_RATIO_CLK_SET(out_clk,		plla_clk,  1, 1);
94 SH_FIXED_RATIO_CLK_SET(p_clk,		plla_clk,  1, 1);
95 SH_FIXED_RATIO_CLK_SET(g_clk,		plla_clk,  1, 1);
96 SH_FIXED_RATIO_CLK_SET(z_clk,		pllb_clk,  1, 1);
97 
98 static struct clk *main_clks[] = {
99 	&extal_clk,
100 	&plla_clk,
101 	&pllb_clk,
102 	&i_clk,
103 	&s_clk,
104 	&s1_clk,
105 	&s3_clk,
106 	&s4_clk,
107 	&b_clk,
108 	&out_clk,
109 	&p_clk,
110 	&g_clk,
111 	&z_clk,
112 	&audio_clk_a,
113 	&audio_clk_b,
114 	&audio_clk_c,
115 };
116 
117 enum {
118 	MSTP531, MSTP530,
119 	MSTP529, MSTP528, MSTP527, MSTP526, MSTP525, MSTP524, MSTP523,
120 	MSTP331,
121 	MSTP323, MSTP322, MSTP321,
122 	MSTP311, MSTP310,
123 	MSTP309, MSTP308, MSTP307,
124 	MSTP114,
125 	MSTP110, MSTP109,
126 	MSTP100,
127 	MSTP030,
128 	MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
129 	MSTP016, MSTP015, MSTP012, MSTP011, MSTP010,
130 	MSTP009, MSTP008, MSTP007,
131 	MSTP_NR };
132 
133 static struct clk mstp_clks[MSTP_NR] = {
134 	[MSTP531] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 31, 0), /* SCU0 */
135 	[MSTP530] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 30, 0), /* SCU1 */
136 	[MSTP529] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 29, 0), /* SCU2 */
137 	[MSTP528] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 28, 0), /* SCU3 */
138 	[MSTP527] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 27, 0), /* SCU4 */
139 	[MSTP526] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 26, 0), /* SCU5 */
140 	[MSTP525] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 25, 0), /* SCU6 */
141 	[MSTP524] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 24, 0), /* SCU7 */
142 	[MSTP523] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 23, 0), /* SCU8 */
143 	[MSTP331] = SH_CLK_MSTP32(&s4_clk, MSTPCR3, 31, 0), /* MMC */
144 	[MSTP323] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 23, 0), /* SDHI0 */
145 	[MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */
146 	[MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */
147 	[MSTP311] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 11, 0), /* SSI4 */
148 	[MSTP310] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 10, 0), /* SSI5 */
149 	[MSTP309] = SH_CLK_MSTP32(&p_clk, MSTPCR3,  9, 0), /* SSI6 */
150 	[MSTP308] = SH_CLK_MSTP32(&p_clk, MSTPCR3,  8, 0), /* SSI7 */
151 	[MSTP307] = SH_CLK_MSTP32(&p_clk, MSTPCR3,  7, 0), /* SSI8 */
152 	[MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */
153 	[MSTP110] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 10, 0), /* VIN0 */
154 	[MSTP109] = SH_CLK_MSTP32(&s_clk, MSTPCR1,  9, 0), /* VIN1 */
155 	[MSTP100] = SH_CLK_MSTP32(&p_clk, MSTPCR1,  0, 0), /* USB0/1 */
156 	[MSTP030] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 30, 0), /* I2C0 */
157 	[MSTP029] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 29, 0), /* I2C1 */
158 	[MSTP028] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 28, 0), /* I2C2 */
159 	[MSTP027] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 27, 0), /* I2C3 */
160 	[MSTP026] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 26, 0), /* SCIF0 */
161 	[MSTP025] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 25, 0), /* SCIF1 */
162 	[MSTP024] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 24, 0), /* SCIF2 */
163 	[MSTP023] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 23, 0), /* SCIF3 */
164 	[MSTP022] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 22, 0), /* SCIF4 */
165 	[MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */
166 	[MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */
167 	[MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */
168 	[MSTP012] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 12, 0), /* SSI0 */
169 	[MSTP011] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 11, 0), /* SSI1 */
170 	[MSTP010] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 10, 0), /* SSI2 */
171 	[MSTP009] = SH_CLK_MSTP32(&p_clk, MSTPCR0,  9, 0), /* SSI3 */
172 	[MSTP008] = SH_CLK_MSTP32(&p_clk, MSTPCR0,  8, 0), /* SRU */
173 	[MSTP007] = SH_CLK_MSTP32(&s_clk, MSTPCR0,  7, 0), /* HSPI */
174 };
175 
176 static struct clk_lookup lookups[] = {
177 	/* main */
178 	CLKDEV_CON_ID("shyway_clk",	&s_clk),
179 	CLKDEV_CON_ID("peripheral_clk",	&p_clk),
180 
181 	/* MSTP32 clocks */
182 	CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP331]), /* MMC */
183 	CLKDEV_DEV_ID("ffe4e000.mmc", &mstp_clks[MSTP331]), /* MMC */
184 	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
185 	CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */
186 	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
187 	CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */
188 	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
189 	CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP321]), /* SDHI2 */
190 	CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
191 	CLKDEV_DEV_ID("r8a7778-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
192 	CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
193 	CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
194 	CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
195 	CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP100]), /* USB FUNC */
196 	CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
197 	CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
198 	CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
199 	CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
200 	CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
201 	CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
202 	CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
203 	CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
204 	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
205 	CLKDEV_DEV_ID("ffe40000.serial", &mstp_clks[MSTP026]), /* SCIF0 */
206 	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
207 	CLKDEV_DEV_ID("ffe41000.serial", &mstp_clks[MSTP025]), /* SCIF1 */
208 	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
209 	CLKDEV_DEV_ID("ffe42000.serial", &mstp_clks[MSTP024]), /* SCIF2 */
210 	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
211 	CLKDEV_DEV_ID("ffe43000.serial", &mstp_clks[MSTP023]), /* SCIF3 */
212 	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
213 	CLKDEV_DEV_ID("ffe44000.serial", &mstp_clks[MSTP022]), /* SCIF4 */
214 	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
215 	CLKDEV_DEV_ID("ffe45000.serial", &mstp_clks[MSTP021]), /* SCIF5 */
216 	CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
217 	CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */
218 	CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
219 	CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */
220 	CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
221 	CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
222 	CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */
223 
224 	CLKDEV_ICK_ID("clk_a", "rcar_sound", &audio_clk_a),
225 	CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b),
226 	CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c),
227 	CLKDEV_ICK_ID("clk_i", "rcar_sound", &s1_clk),
228 	CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]),
229 	CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP011]),
230 	CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP010]),
231 	CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP009]),
232 	CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP311]),
233 	CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP310]),
234 	CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]),
235 	CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]),
236 	CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]),
237 	CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP531]),
238 	CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP530]),
239 	CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP529]),
240 	CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP528]),
241 	CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP527]),
242 	CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP526]),
243 	CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP525]),
244 	CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP524]),
245 	CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP523]),
246 	CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]),
247 	CLKDEV_ICK_ID("fck", "ffd80000.timer", &mstp_clks[MSTP016]),
248 	CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP015]),
249 	CLKDEV_ICK_ID("fck", "ffd81000.timer", &mstp_clks[MSTP015]),
250 };
251 
r8a7778_clock_init(void)252 void __init r8a7778_clock_init(void)
253 {
254 	void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
255 	u32 mode;
256 	int k, ret = 0;
257 
258 	BUG_ON(!modemr);
259 	mode = ioread32(modemr);
260 	iounmap(modemr);
261 
262 	switch (mode & (MD(19) | MD(18) | MD(12) | MD(11))) {
263 	case MD(19):
264 		extal_clk.rate = 38000000;
265 		SH_CLK_SET_RATIO(&plla_clk_ratio,	21, 1);
266 		SH_CLK_SET_RATIO(&pllb_clk_ratio,	21, 1);
267 		break;
268 	case MD(19) | MD(11):
269 		extal_clk.rate = 33333333;
270 		SH_CLK_SET_RATIO(&plla_clk_ratio,	24, 1);
271 		SH_CLK_SET_RATIO(&pllb_clk_ratio,	24, 1);
272 		break;
273 	case MD(19) | MD(12):
274 		extal_clk.rate = 28500000;
275 		SH_CLK_SET_RATIO(&plla_clk_ratio,	28, 1);
276 		SH_CLK_SET_RATIO(&pllb_clk_ratio,	28, 1);
277 		break;
278 	case MD(19) | MD(12) | MD(11):
279 		extal_clk.rate = 25000000;
280 		SH_CLK_SET_RATIO(&plla_clk_ratio,	32, 1);
281 		SH_CLK_SET_RATIO(&pllb_clk_ratio,	32, 1);
282 		break;
283 	case MD(19) | MD(18) | MD(11):
284 		extal_clk.rate = 33333333;
285 		SH_CLK_SET_RATIO(&plla_clk_ratio,	24, 1);
286 		SH_CLK_SET_RATIO(&pllb_clk_ratio,	21, 1);
287 		break;
288 	case MD(19) | MD(18) | MD(12):
289 		extal_clk.rate = 28500000;
290 		SH_CLK_SET_RATIO(&plla_clk_ratio,	28, 1);
291 		SH_CLK_SET_RATIO(&pllb_clk_ratio,	21, 1);
292 		break;
293 	case MD(19) | MD(18) | MD(12) | MD(11):
294 		extal_clk.rate = 25000000;
295 		SH_CLK_SET_RATIO(&plla_clk_ratio,	32, 1);
296 		SH_CLK_SET_RATIO(&pllb_clk_ratio,	24, 1);
297 		break;
298 	default:
299 		BUG();
300 	}
301 
302 	if (mode & MD(1)) {
303 		SH_CLK_SET_RATIO(&i_clk_ratio,	1, 1);
304 		SH_CLK_SET_RATIO(&s_clk_ratio,	1, 3);
305 		SH_CLK_SET_RATIO(&s1_clk_ratio,	1, 6);
306 		SH_CLK_SET_RATIO(&s3_clk_ratio,	1, 4);
307 		SH_CLK_SET_RATIO(&s4_clk_ratio,	1, 8);
308 		SH_CLK_SET_RATIO(&p_clk_ratio,	1, 12);
309 		SH_CLK_SET_RATIO(&g_clk_ratio,	1, 12);
310 		if (mode & MD(2)) {
311 			SH_CLK_SET_RATIO(&b_clk_ratio,		1, 18);
312 			SH_CLK_SET_RATIO(&out_clk_ratio,	1, 18);
313 		} else {
314 			SH_CLK_SET_RATIO(&b_clk_ratio,		1, 12);
315 			SH_CLK_SET_RATIO(&out_clk_ratio,	1, 12);
316 		}
317 	} else {
318 		SH_CLK_SET_RATIO(&i_clk_ratio,	1, 1);
319 		SH_CLK_SET_RATIO(&s_clk_ratio,	1, 4);
320 		SH_CLK_SET_RATIO(&s1_clk_ratio,	1, 8);
321 		SH_CLK_SET_RATIO(&s3_clk_ratio,	1, 4);
322 		SH_CLK_SET_RATIO(&s4_clk_ratio,	1, 8);
323 		SH_CLK_SET_RATIO(&p_clk_ratio,	1, 16);
324 		SH_CLK_SET_RATIO(&g_clk_ratio,	1, 12);
325 		if (mode & MD(2)) {
326 			SH_CLK_SET_RATIO(&b_clk_ratio,		1, 16);
327 			SH_CLK_SET_RATIO(&out_clk_ratio,	1, 16);
328 		} else {
329 			SH_CLK_SET_RATIO(&b_clk_ratio,		1, 12);
330 			SH_CLK_SET_RATIO(&out_clk_ratio,	1, 12);
331 		}
332 	}
333 
334 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
335 		ret = clk_register(main_clks[k]);
336 
337 	if (!ret)
338 		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
339 
340 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
341 
342 	if (!ret)
343 		shmobile_clk_init();
344 	else
345 		panic("failed to setup r8a7778 clocks\n");
346 }
347