• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <linux/sh_timer.h>
27 
28 #include "clock.h"
29 #include "common.h"
30 #include "r8a7779.h"
31 
32 /*
33  *		MD1 = 1			MD1 = 0
34  *		(PLLA = 1500)		(PLLA = 1600)
35  *		(MHz)			(MHz)
36  *------------------------------------------------+--------------------
37  * clkz		1000   (2/3)		800   (1/2)
38  * clkzs	 250   (1/6)		200   (1/8)
39  * clki		 750   (1/2)		800   (1/2)
40  * clks		 250   (1/6)		200   (1/8)
41  * clks1	 125   (1/12)		100   (1/16)
42  * clks3	 187.5 (1/8)		200   (1/8)
43  * clks4	  93.7 (1/16)		100   (1/16)
44  * clkp		  62.5 (1/24)		 50   (1/32)
45  * clkg		  62.5 (1/24)		 66.6 (1/24)
46  * clkb, CLKOUT
47  * (MD2 = 0)	  62.5 (1/24)		 66.6 (1/24)
48  * (MD2 = 1)	  41.6 (1/36)		 50   (1/32)
49 */
50 
51 #define MD(nr)	BIT(nr)
52 
53 #define MSTPCR0		IOMEM(0xffc80030)
54 #define MSTPCR1		IOMEM(0xffc80034)
55 #define MSTPCR3		IOMEM(0xffc8003c)
56 #define MSTPSR1		IOMEM(0xffc80044)
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 /*
68  * Default rate for the root input clock, reset this with clk_set_rate()
69  * from the platform code.
70  */
71 static struct clk plla_clk = {
72 	/* .rate will be updated on r8a7779_clock_init() */
73 	.mapping	= &cpg_mapping,
74 };
75 
76 /*
77  * clock ratio of these clock will be updated
78  * on r8a7779_clock_init()
79  */
80 SH_FIXED_RATIO_CLK_SET(clkz_clk,	plla_clk, 1, 1);
81 SH_FIXED_RATIO_CLK_SET(clkzs_clk,	plla_clk, 1, 1);
82 SH_FIXED_RATIO_CLK_SET(clki_clk,	plla_clk, 1, 1);
83 SH_FIXED_RATIO_CLK_SET(clks_clk,	plla_clk, 1, 1);
84 SH_FIXED_RATIO_CLK_SET(clks1_clk,	plla_clk, 1, 1);
85 SH_FIXED_RATIO_CLK_SET(clks3_clk,	plla_clk, 1, 1);
86 SH_FIXED_RATIO_CLK_SET(clks4_clk,	plla_clk, 1, 1);
87 SH_FIXED_RATIO_CLK_SET(clkb_clk,	plla_clk, 1, 1);
88 SH_FIXED_RATIO_CLK_SET(clkout_clk,	plla_clk, 1, 1);
89 SH_FIXED_RATIO_CLK_SET(clkp_clk,	plla_clk, 1, 1);
90 SH_FIXED_RATIO_CLK_SET(clkg_clk,	plla_clk, 1, 1);
91 
92 static struct clk *main_clks[] = {
93 	&plla_clk,
94 	&clkz_clk,
95 	&clkzs_clk,
96 	&clki_clk,
97 	&clks_clk,
98 	&clks1_clk,
99 	&clks3_clk,
100 	&clks4_clk,
101 	&clkb_clk,
102 	&clkout_clk,
103 	&clkp_clk,
104 	&clkg_clk,
105 };
106 
107 enum { MSTP323, MSTP322, MSTP321, MSTP320,
108 	MSTP120,
109 	MSTP116, MSTP115, MSTP114,
110 	MSTP110, MSTP109, MSTP108,
111 	MSTP103, MSTP101, MSTP100,
112 	MSTP030,
113 	MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
114 	MSTP016, MSTP015, MSTP014,
115 	MSTP007,
116 	MSTP_NR };
117 
118 static struct clk mstp_clks[MSTP_NR] = {
119 	[MSTP323] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 23, 0), /* SDHI0 */
120 	[MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */
121 	[MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
122 	[MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
123 	[MSTP120] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 20, MSTPSR1, 0), /* VIN3 */
124 	[MSTP116] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 16, MSTPSR1, 0), /* PCIe */
125 	[MSTP115] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 15, MSTPSR1, 0), /* SATA */
126 	[MSTP114] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 14, MSTPSR1, 0), /* Ether */
127 	[MSTP110] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 10, MSTPSR1, 0), /* VIN0 */
128 	[MSTP109] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1,  9, MSTPSR1, 0), /* VIN1 */
129 	[MSTP108] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1,  8, MSTPSR1, 0), /* VIN2 */
130 	[MSTP103] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1,  3, MSTPSR1, 0), /* DU */
131 	[MSTP101] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1,  1, MSTPSR1, 0), /* USB2 */
132 	[MSTP100] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1,  0, MSTPSR1, 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 */
147 };
148 
149 static struct clk_lookup lookups[] = {
150 	/* main clocks */
151 	CLKDEV_CON_ID("plla_clk", &plla_clk),
152 	CLKDEV_CON_ID("clkz_clk", &clkz_clk),
153 	CLKDEV_CON_ID("clkzs_clk", &clkzs_clk),
154 
155 	/* DIV4 clocks */
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),
162 
163 	/* MSTP32 clocks */
164 	CLKDEV_DEV_ID("r8a7779-vin.3", &mstp_clks[MSTP120]), /* VIN3 */
165 	CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */
166 	CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
167 	CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
168 	CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
169 	CLKDEV_DEV_ID("r8a7779-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
170 	CLKDEV_DEV_ID("r8a7779-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
171 	CLKDEV_DEV_ID("r8a7779-vin.2", &mstp_clks[MSTP108]), /* VIN2 */
172 	CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
173 	CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
174 	CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
175 	CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
176 	CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]), /* TMU0 */
177 	CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
178 	CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
179 	CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
180 	CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
181 	CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
182 	CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
183 	CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
184 	CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
185 	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
186 	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
187 	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
188 	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
189 	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
190 	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
191 	CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
192 	CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */
193 	CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
194 	CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */
195 	CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
196 	CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
197 	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
198 	CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */
199 	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
200 	CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */
201 	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
202 	CLKDEV_DEV_ID("ffe4e000.sd", &mstp_clks[MSTP321]), /* SDHI2 */
203 	CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */
204 	CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP320]), /* SDHI3 */
205 	CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */
206 };
207 
r8a7779_clock_init(void)208 void __init r8a7779_clock_init(void)
209 {
210 	u32 mode = r8a7779_read_mode_pins();
211 	int k, ret = 0;
212 
213 	if (mode & MD(1)) {
214 		plla_clk.rate = 1500000000;
215 
216 		SH_CLK_SET_RATIO(&clkz_clk_ratio,	2, 3);
217 		SH_CLK_SET_RATIO(&clkzs_clk_ratio,	1, 6);
218 		SH_CLK_SET_RATIO(&clki_clk_ratio,	1, 2);
219 		SH_CLK_SET_RATIO(&clks_clk_ratio,	1, 6);
220 		SH_CLK_SET_RATIO(&clks1_clk_ratio,	1, 12);
221 		SH_CLK_SET_RATIO(&clks3_clk_ratio,	1, 8);
222 		SH_CLK_SET_RATIO(&clks4_clk_ratio,	1, 16);
223 		SH_CLK_SET_RATIO(&clkp_clk_ratio,	1, 24);
224 		SH_CLK_SET_RATIO(&clkg_clk_ratio,	1, 24);
225 		if (mode & MD(2)) {
226 			SH_CLK_SET_RATIO(&clkb_clk_ratio,	1, 36);
227 			SH_CLK_SET_RATIO(&clkout_clk_ratio,	1, 36);
228 		} else {
229 			SH_CLK_SET_RATIO(&clkb_clk_ratio,	1, 24);
230 			SH_CLK_SET_RATIO(&clkout_clk_ratio,	1, 24);
231 		}
232 	} else {
233 		plla_clk.rate = 1600000000;
234 
235 		SH_CLK_SET_RATIO(&clkz_clk_ratio,	1, 2);
236 		SH_CLK_SET_RATIO(&clkzs_clk_ratio,	1, 8);
237 		SH_CLK_SET_RATIO(&clki_clk_ratio,	1, 2);
238 		SH_CLK_SET_RATIO(&clks_clk_ratio,	1, 8);
239 		SH_CLK_SET_RATIO(&clks1_clk_ratio,	1, 16);
240 		SH_CLK_SET_RATIO(&clks3_clk_ratio,	1, 8);
241 		SH_CLK_SET_RATIO(&clks4_clk_ratio,	1, 16);
242 		SH_CLK_SET_RATIO(&clkp_clk_ratio,	1, 32);
243 		SH_CLK_SET_RATIO(&clkg_clk_ratio,	1, 24);
244 		if (mode & MD(2)) {
245 			SH_CLK_SET_RATIO(&clkb_clk_ratio,	1, 32);
246 			SH_CLK_SET_RATIO(&clkout_clk_ratio,	1, 32);
247 		} else {
248 			SH_CLK_SET_RATIO(&clkb_clk_ratio,	1, 24);
249 			SH_CLK_SET_RATIO(&clkout_clk_ratio,	1, 24);
250 		}
251 	}
252 
253 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
254 		ret = clk_register(main_clks[k]);
255 
256 	if (!ret)
257 		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
258 
259 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
260 
261 	if (!ret)
262 		shmobile_clk_init();
263 	else
264 		panic("failed to setup r8a7779 clocks\n");
265 }
266 
267 /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
r8a7779_register_twd(void)268 void __init __weak r8a7779_register_twd(void) { }
269 
r8a7779_earlytimer_init(void)270 void __init r8a7779_earlytimer_init(void)
271 {
272 	r8a7779_clock_init();
273 	r8a7779_register_twd();
274 	shmobile_earlytimer_init();
275 }
276