xref: /openbmc/linux/drivers/clk/bcm/clk-bcm281xx.c (revision f7018c21)
1 /*
2  * Copyright (C) 2013 Broadcom Corporation
3  * Copyright 2013 Linaro Limited
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation version 2.
8  *
9  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
10  * kind, whether express or implied; without even the implied warranty
11  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14 
15 #include "clk-kona.h"
16 #include "dt-bindings/clock/bcm281xx.h"
17 
18 /* bcm11351 CCU device tree "compatible" strings */
19 #define BCM11351_DT_ROOT_CCU_COMPAT	"brcm,bcm11351-root-ccu"
20 #define BCM11351_DT_AON_CCU_COMPAT	"brcm,bcm11351-aon-ccu"
21 #define BCM11351_DT_HUB_CCU_COMPAT	"brcm,bcm11351-hub-ccu"
22 #define BCM11351_DT_MASTER_CCU_COMPAT	"brcm,bcm11351-master-ccu"
23 #define BCM11351_DT_SLAVE_CCU_COMPAT	"brcm,bcm11351-slave-ccu"
24 
25 /* Root CCU clocks */
26 
27 static struct peri_clk_data frac_1m_data = {
28 	.gate		= HW_SW_GATE(0x214, 16, 0, 1),
29 	.trig		= TRIGGER(0x0e04, 0),
30 	.div		= FRAC_DIVIDER(0x0e00, 0, 22, 16),
31 	.clocks		= CLOCKS("ref_crystal"),
32 };
33 
34 /* AON CCU clocks */
35 
36 static struct peri_clk_data hub_timer_data = {
37 	.gate		= HW_SW_GATE(0x0414, 16, 0, 1),
38 	.clocks		= CLOCKS("bbl_32k",
39 				 "frac_1m",
40 				 "dft_19_5m"),
41 	.sel		= SELECTOR(0x0a10, 0, 2),
42 	.trig		= TRIGGER(0x0a40, 4),
43 };
44 
45 static struct peri_clk_data pmu_bsc_data = {
46 	.gate		= HW_SW_GATE(0x0418, 16, 0, 1),
47 	.clocks		= CLOCKS("ref_crystal",
48 				 "pmu_bsc_var",
49 				 "bbl_32k"),
50 	.sel		= SELECTOR(0x0a04, 0, 2),
51 	.div		= DIVIDER(0x0a04, 3, 4),
52 	.trig		= TRIGGER(0x0a40, 0),
53 };
54 
55 static struct peri_clk_data pmu_bsc_var_data = {
56 	.clocks		= CLOCKS("var_312m",
57 				 "ref_312m"),
58 	.sel		= SELECTOR(0x0a00, 0, 2),
59 	.div		= DIVIDER(0x0a00, 4, 5),
60 	.trig		= TRIGGER(0x0a40, 2),
61 };
62 
63 /* Hub CCU clocks */
64 
65 static struct peri_clk_data tmon_1m_data = {
66 	.gate		= HW_SW_GATE(0x04a4, 18, 2, 3),
67 	.clocks		= CLOCKS("ref_crystal",
68 				 "frac_1m"),
69 	.sel		= SELECTOR(0x0e74, 0, 2),
70 	.trig		= TRIGGER(0x0e84, 1),
71 };
72 
73 /* Master CCU clocks */
74 
75 static struct peri_clk_data sdio1_data = {
76 	.gate		= HW_SW_GATE(0x0358, 18, 2, 3),
77 	.clocks		= CLOCKS("ref_crystal",
78 				 "var_52m",
79 				 "ref_52m",
80 				 "var_96m",
81 				 "ref_96m"),
82 	.sel		= SELECTOR(0x0a28, 0, 3),
83 	.div		= DIVIDER(0x0a28, 4, 14),
84 	.trig		= TRIGGER(0x0afc, 9),
85 };
86 
87 static struct peri_clk_data sdio2_data = {
88 	.gate		= HW_SW_GATE(0x035c, 18, 2, 3),
89 	.clocks		= CLOCKS("ref_crystal",
90 				 "var_52m",
91 				 "ref_52m",
92 				 "var_96m",
93 				 "ref_96m"),
94 	.sel		= SELECTOR(0x0a2c, 0, 3),
95 	.div		= DIVIDER(0x0a2c, 4, 14),
96 	.trig		= TRIGGER(0x0afc, 10),
97 };
98 
99 static struct peri_clk_data sdio3_data = {
100 	.gate		= HW_SW_GATE(0x0364, 18, 2, 3),
101 	.clocks		= CLOCKS("ref_crystal",
102 				 "var_52m",
103 				 "ref_52m",
104 				 "var_96m",
105 				 "ref_96m"),
106 	.sel		= SELECTOR(0x0a34, 0, 3),
107 	.div		= DIVIDER(0x0a34, 4, 14),
108 	.trig		= TRIGGER(0x0afc, 12),
109 };
110 
111 static struct peri_clk_data sdio4_data = {
112 	.gate		= HW_SW_GATE(0x0360, 18, 2, 3),
113 	.clocks		= CLOCKS("ref_crystal",
114 				 "var_52m",
115 				 "ref_52m",
116 				 "var_96m",
117 				 "ref_96m"),
118 	.sel		= SELECTOR(0x0a30, 0, 3),
119 	.div		= DIVIDER(0x0a30, 4, 14),
120 	.trig		= TRIGGER(0x0afc, 11),
121 };
122 
123 static struct peri_clk_data usb_ic_data = {
124 	.gate		= HW_SW_GATE(0x0354, 18, 2, 3),
125 	.clocks		= CLOCKS("ref_crystal",
126 				 "var_96m",
127 				 "ref_96m"),
128 	.div		= FIXED_DIVIDER(2),
129 	.sel		= SELECTOR(0x0a24, 0, 2),
130 	.trig		= TRIGGER(0x0afc, 7),
131 };
132 
133 /* also called usbh_48m */
134 static struct peri_clk_data hsic2_48m_data = {
135 	.gate		= HW_SW_GATE(0x0370, 18, 2, 3),
136 	.clocks		= CLOCKS("ref_crystal",
137 				 "var_96m",
138 				 "ref_96m"),
139 	.sel		= SELECTOR(0x0a38, 0, 2),
140 	.div		= FIXED_DIVIDER(2),
141 	.trig		= TRIGGER(0x0afc, 5),
142 };
143 
144 /* also called usbh_12m */
145 static struct peri_clk_data hsic2_12m_data = {
146 	.gate		= HW_SW_GATE(0x0370, 20, 4, 5),
147 	.div		= DIVIDER(0x0a38, 12, 2),
148 	.clocks		= CLOCKS("ref_crystal",
149 				 "var_96m",
150 				 "ref_96m"),
151 	.pre_div	= FIXED_DIVIDER(2),
152 	.sel		= SELECTOR(0x0a38, 0, 2),
153 	.trig		= TRIGGER(0x0afc, 5),
154 };
155 
156 /* Slave CCU clocks */
157 
158 static struct peri_clk_data uartb_data = {
159 	.gate		= HW_SW_GATE(0x0400, 18, 2, 3),
160 	.clocks		= CLOCKS("ref_crystal",
161 				 "var_156m",
162 				 "ref_156m"),
163 	.sel		= SELECTOR(0x0a10, 0, 2),
164 	.div		= FRAC_DIVIDER(0x0a10, 4, 12, 8),
165 	.trig		= TRIGGER(0x0afc, 2),
166 };
167 
168 static struct peri_clk_data uartb2_data = {
169 	.gate		= HW_SW_GATE(0x0404, 18, 2, 3),
170 	.clocks		= CLOCKS("ref_crystal",
171 				 "var_156m",
172 				 "ref_156m"),
173 	.sel		= SELECTOR(0x0a14, 0, 2),
174 	.div		= FRAC_DIVIDER(0x0a14, 4, 12, 8),
175 	.trig		= TRIGGER(0x0afc, 3),
176 };
177 
178 static struct peri_clk_data uartb3_data = {
179 	.gate		= HW_SW_GATE(0x0408, 18, 2, 3),
180 	.clocks		= CLOCKS("ref_crystal",
181 				 "var_156m",
182 				 "ref_156m"),
183 	.sel		= SELECTOR(0x0a18, 0, 2),
184 	.div		= FRAC_DIVIDER(0x0a18, 4, 12, 8),
185 	.trig		= TRIGGER(0x0afc, 4),
186 };
187 
188 static struct peri_clk_data uartb4_data = {
189 	.gate		= HW_SW_GATE(0x0408, 18, 2, 3),
190 	.clocks		= CLOCKS("ref_crystal",
191 				 "var_156m",
192 				 "ref_156m"),
193 	.sel		= SELECTOR(0x0a1c, 0, 2),
194 	.div		= FRAC_DIVIDER(0x0a1c, 4, 12, 8),
195 	.trig		= TRIGGER(0x0afc, 5),
196 };
197 
198 static struct peri_clk_data ssp0_data = {
199 	.gate		= HW_SW_GATE(0x0410, 18, 2, 3),
200 	.clocks		= CLOCKS("ref_crystal",
201 				 "var_104m",
202 				 "ref_104m",
203 				 "var_96m",
204 				 "ref_96m"),
205 	.sel		= SELECTOR(0x0a20, 0, 3),
206 	.div		= DIVIDER(0x0a20, 4, 14),
207 	.trig		= TRIGGER(0x0afc, 6),
208 };
209 
210 static struct peri_clk_data ssp2_data = {
211 	.gate		= HW_SW_GATE(0x0418, 18, 2, 3),
212 	.clocks		= CLOCKS("ref_crystal",
213 				 "var_104m",
214 				 "ref_104m",
215 				 "var_96m",
216 				 "ref_96m"),
217 	.sel		= SELECTOR(0x0a28, 0, 3),
218 	.div		= DIVIDER(0x0a28, 4, 14),
219 	.trig		= TRIGGER(0x0afc, 8),
220 };
221 
222 static struct peri_clk_data bsc1_data = {
223 	.gate		= HW_SW_GATE(0x0458, 18, 2, 3),
224 	.clocks		= CLOCKS("ref_crystal",
225 				 "var_104m",
226 				 "ref_104m",
227 				 "var_13m",
228 				 "ref_13m"),
229 	.sel		= SELECTOR(0x0a64, 0, 3),
230 	.trig		= TRIGGER(0x0afc, 23),
231 };
232 
233 static struct peri_clk_data bsc2_data = {
234 	.gate		= HW_SW_GATE(0x045c, 18, 2, 3),
235 	.clocks	= CLOCKS("ref_crystal",
236 				 "var_104m",
237 				 "ref_104m",
238 				 "var_13m",
239 				 "ref_13m"),
240 	.sel		= SELECTOR(0x0a68, 0, 3),
241 	.trig		= TRIGGER(0x0afc, 24),
242 };
243 
244 static struct peri_clk_data bsc3_data = {
245 	.gate		= HW_SW_GATE(0x0484, 18, 2, 3),
246 	.clocks		= CLOCKS("ref_crystal",
247 				 "var_104m",
248 				 "ref_104m",
249 				 "var_13m",
250 				 "ref_13m"),
251 	.sel		= SELECTOR(0x0a84, 0, 3),
252 	.trig		= TRIGGER(0x0b00, 2),
253 };
254 
255 static struct peri_clk_data pwm_data = {
256 	.gate		= HW_SW_GATE(0x0468, 18, 2, 3),
257 	.clocks		= CLOCKS("ref_crystal",
258 				 "var_104m"),
259 	.sel		= SELECTOR(0x0a70, 0, 2),
260 	.div		= DIVIDER(0x0a70, 4, 3),
261 	.trig		= TRIGGER(0x0afc, 15),
262 };
263 
264 /*
265  * CCU setup routines
266  *
267  * These are called from kona_dt_ccu_setup() to initialize the array
268  * of clocks provided by the CCU.  Once allocated, the entries in
269  * the array are initialized by calling kona_clk_setup() with the
270  * initialization data for each clock.  They return 0 if successful
271  * or an error code otherwise.
272  */
273 static int __init bcm281xx_root_ccu_clks_setup(struct ccu_data *ccu)
274 {
275 	struct clk **clks;
276 	size_t count = BCM281XX_ROOT_CCU_CLOCK_COUNT;
277 
278 	clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
279 	if (!clks) {
280 		pr_err("%s: failed to allocate root clocks\n", __func__);
281 		return -ENOMEM;
282 	}
283 	ccu->data.clks = clks;
284 	ccu->data.clk_num = count;
285 
286 	PERI_CLK_SETUP(clks, ccu, BCM281XX_ROOT_CCU_FRAC_1M, frac_1m);
287 
288 	return 0;
289 }
290 
291 static int __init bcm281xx_aon_ccu_clks_setup(struct ccu_data *ccu)
292 {
293 	struct clk **clks;
294 	size_t count = BCM281XX_AON_CCU_CLOCK_COUNT;
295 
296 	clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
297 	if (!clks) {
298 		pr_err("%s: failed to allocate aon clocks\n", __func__);
299 		return -ENOMEM;
300 	}
301 	ccu->data.clks = clks;
302 	ccu->data.clk_num = count;
303 
304 	PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_HUB_TIMER, hub_timer);
305 	PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_PMU_BSC, pmu_bsc);
306 	PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_PMU_BSC_VAR, pmu_bsc_var);
307 
308 	return 0;
309 }
310 
311 static int __init bcm281xx_hub_ccu_clks_setup(struct ccu_data *ccu)
312 {
313 	struct clk **clks;
314 	size_t count = BCM281XX_HUB_CCU_CLOCK_COUNT;
315 
316 	clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
317 	if (!clks) {
318 		pr_err("%s: failed to allocate hub clocks\n", __func__);
319 		return -ENOMEM;
320 	}
321 	ccu->data.clks = clks;
322 	ccu->data.clk_num = count;
323 
324 	PERI_CLK_SETUP(clks, ccu, BCM281XX_HUB_CCU_TMON_1M, tmon_1m);
325 
326 	return 0;
327 }
328 
329 static int __init bcm281xx_master_ccu_clks_setup(struct ccu_data *ccu)
330 {
331 	struct clk **clks;
332 	size_t count = BCM281XX_MASTER_CCU_CLOCK_COUNT;
333 
334 	clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
335 	if (!clks) {
336 		pr_err("%s: failed to allocate master clocks\n", __func__);
337 		return -ENOMEM;
338 	}
339 	ccu->data.clks = clks;
340 	ccu->data.clk_num = count;
341 
342 	PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO1, sdio1);
343 	PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO2, sdio2);
344 	PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO3, sdio3);
345 	PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO4, sdio4);
346 	PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_USB_IC, usb_ic);
347 	PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_HSIC2_48M, hsic2_48m);
348 	PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_HSIC2_12M, hsic2_12m);
349 
350 	return 0;
351 }
352 
353 static int __init bcm281xx_slave_ccu_clks_setup(struct ccu_data *ccu)
354 {
355 	struct clk **clks;
356 	size_t count = BCM281XX_SLAVE_CCU_CLOCK_COUNT;
357 
358 	clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
359 	if (!clks) {
360 		pr_err("%s: failed to allocate slave clocks\n", __func__);
361 		return -ENOMEM;
362 	}
363 	ccu->data.clks = clks;
364 	ccu->data.clk_num = count;
365 
366 	PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB, uartb);
367 	PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB2, uartb2);
368 	PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB3, uartb3);
369 	PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB4, uartb4);
370 	PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_SSP0, ssp0);
371 	PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_SSP2, ssp2);
372 	PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC1, bsc1);
373 	PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC2, bsc2);
374 	PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC3, bsc3);
375 	PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_PWM, pwm);
376 
377 	return 0;
378 }
379 
380 /* Device tree match table callback functions */
381 
382 static void __init kona_dt_root_ccu_setup(struct device_node *node)
383 {
384 	kona_dt_ccu_setup(node, bcm281xx_root_ccu_clks_setup);
385 }
386 
387 static void __init kona_dt_aon_ccu_setup(struct device_node *node)
388 {
389 	kona_dt_ccu_setup(node, bcm281xx_aon_ccu_clks_setup);
390 }
391 
392 static void __init kona_dt_hub_ccu_setup(struct device_node *node)
393 {
394 	kona_dt_ccu_setup(node, bcm281xx_hub_ccu_clks_setup);
395 }
396 
397 static void __init kona_dt_master_ccu_setup(struct device_node *node)
398 {
399 	kona_dt_ccu_setup(node, bcm281xx_master_ccu_clks_setup);
400 }
401 
402 static void __init kona_dt_slave_ccu_setup(struct device_node *node)
403 {
404 	kona_dt_ccu_setup(node, bcm281xx_slave_ccu_clks_setup);
405 }
406 
407 CLK_OF_DECLARE(bcm11351_root_ccu, BCM11351_DT_ROOT_CCU_COMPAT,
408 			kona_dt_root_ccu_setup);
409 CLK_OF_DECLARE(bcm11351_aon_ccu, BCM11351_DT_AON_CCU_COMPAT,
410 			kona_dt_aon_ccu_setup);
411 CLK_OF_DECLARE(bcm11351_hub_ccu, BCM11351_DT_HUB_CCU_COMPAT,
412 			kona_dt_hub_ccu_setup);
413 CLK_OF_DECLARE(bcm11351_master_ccu, BCM11351_DT_MASTER_CCU_COMPAT,
414 			kona_dt_master_ccu_setup);
415 CLK_OF_DECLARE(bcm11351_slave_ccu, BCM11351_DT_SLAVE_CCU_COMPAT,
416 			kona_dt_slave_ccu_setup);
417