clk: bcm281xx: add initial clock framework support
[cascardo/linux.git] / drivers / clk / bcm / clk-bcm281xx.c
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);