Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[pandora-kernel.git] / arch / arm / mach-spear6xx / clock.c
1 /*
2  * arch/arm/mach-spear6xx/clock.c
3  *
4  * SPEAr6xx machines clock framework source file
5  *
6  * Copyright (C) 2009 ST Microelectronics
7  * Viresh Kumar<viresh.kumar@st.com>
8  *
9  * This file is licensed under the terms of the GNU General Public
10  * License version 2. This program is licensed "as is" without any
11  * warranty of any kind, whether express or implied.
12  */
13
14 #include <linux/init.h>
15 #include <linux/kernel.h>
16 #include <mach/misc_regs.h>
17 #include <plat/clock.h>
18
19 /* root clks */
20 /* 32 KHz oscillator clock */
21 static struct clk osc_32k_clk = {
22         .flags = ALWAYS_ENABLED,
23         .rate = 32000,
24 };
25
26 /* 30 MHz oscillator clock */
27 static struct clk osc_30m_clk = {
28         .flags = ALWAYS_ENABLED,
29         .rate = 30000000,
30 };
31
32 /* clock derived from 32 KHz osc clk */
33 /* rtc clock */
34 static struct clk rtc_clk = {
35         .pclk = &osc_32k_clk,
36         .en_reg = PERIP1_CLK_ENB,
37         .en_reg_bit = RTC_CLK_ENB,
38         .recalc = &follow_parent,
39 };
40
41 /* clock derived from 30 MHz osc clk */
42 /* pll1 configuration structure */
43 static struct pll_clk_config pll1_config = {
44         .mode_reg = PLL1_CTR,
45         .cfg_reg = PLL1_FRQ,
46 };
47
48 /* PLL1 clock */
49 static struct clk pll1_clk = {
50         .pclk = &osc_30m_clk,
51         .en_reg = PLL1_CTR,
52         .en_reg_bit = PLL_ENABLE,
53         .recalc = &pll1_clk_recalc,
54         .private_data = &pll1_config,
55 };
56
57 /* PLL3 48 MHz clock */
58 static struct clk pll3_48m_clk = {
59         .flags = ALWAYS_ENABLED,
60         .pclk = &osc_30m_clk,
61         .rate = 48000000,
62 };
63
64 /* watch dog timer clock */
65 static struct clk wdt_clk = {
66         .flags = ALWAYS_ENABLED,
67         .pclk = &osc_30m_clk,
68         .recalc = &follow_parent,
69 };
70
71 /* clock derived from pll1 clk */
72 /* cpu clock */
73 static struct clk cpu_clk = {
74         .flags = ALWAYS_ENABLED,
75         .pclk = &pll1_clk,
76         .recalc = &follow_parent,
77 };
78
79 /* ahb configuration structure */
80 static struct bus_clk_config ahb_config = {
81         .reg = CORE_CLK_CFG,
82         .mask = PLL_HCLK_RATIO_MASK,
83         .shift = PLL_HCLK_RATIO_SHIFT,
84 };
85
86 /* ahb clock */
87 static struct clk ahb_clk = {
88         .flags = ALWAYS_ENABLED,
89         .pclk = &pll1_clk,
90         .recalc = &bus_clk_recalc,
91         .private_data = &ahb_config,
92 };
93
94 /* uart parents */
95 static struct pclk_info uart_pclk_info[] = {
96         {
97                 .pclk = &pll1_clk,
98                 .pclk_mask = AUX_CLK_PLL1_MASK,
99                 .scalable = 1,
100         }, {
101                 .pclk = &pll3_48m_clk,
102                 .pclk_mask = AUX_CLK_PLL3_MASK,
103                 .scalable = 0,
104         },
105 };
106
107 /* uart parent select structure */
108 static struct pclk_sel uart_pclk_sel = {
109         .pclk_info = uart_pclk_info,
110         .pclk_count = ARRAY_SIZE(uart_pclk_info),
111         .pclk_sel_reg = PERIP_CLK_CFG,
112         .pclk_sel_mask = UART_CLK_MASK,
113 };
114
115 /* uart configurations */
116 static struct aux_clk_config uart_config = {
117         .synth_reg = UART_CLK_SYNT,
118 };
119
120 /* uart0 clock */
121 static struct clk uart0_clk = {
122         .en_reg = PERIP1_CLK_ENB,
123         .en_reg_bit = UART0_CLK_ENB,
124         .pclk_sel = &uart_pclk_sel,
125         .pclk_sel_shift = UART_CLK_SHIFT,
126         .recalc = &aux_clk_recalc,
127         .private_data = &uart_config,
128 };
129
130 /* uart1 clock */
131 static struct clk uart1_clk = {
132         .en_reg = PERIP1_CLK_ENB,
133         .en_reg_bit = UART1_CLK_ENB,
134         .pclk_sel = &uart_pclk_sel,
135         .pclk_sel_shift = UART_CLK_SHIFT,
136         .recalc = &aux_clk_recalc,
137         .private_data = &uart_config,
138 };
139
140 /* firda configurations */
141 static struct aux_clk_config firda_config = {
142         .synth_reg = FIRDA_CLK_SYNT,
143 };
144
145 /* firda parents */
146 static struct pclk_info firda_pclk_info[] = {
147         {
148                 .pclk = &pll1_clk,
149                 .pclk_mask = AUX_CLK_PLL1_MASK,
150                 .scalable = 1,
151         }, {
152                 .pclk = &pll3_48m_clk,
153                 .pclk_mask = AUX_CLK_PLL3_MASK,
154                 .scalable = 0,
155         },
156 };
157
158 /* firda parent select structure */
159 static struct pclk_sel firda_pclk_sel = {
160         .pclk_info = firda_pclk_info,
161         .pclk_count = ARRAY_SIZE(firda_pclk_info),
162         .pclk_sel_reg = PERIP_CLK_CFG,
163         .pclk_sel_mask = FIRDA_CLK_MASK,
164 };
165
166 /* firda clock */
167 static struct clk firda_clk = {
168         .en_reg = PERIP1_CLK_ENB,
169         .en_reg_bit = FIRDA_CLK_ENB,
170         .pclk_sel = &firda_pclk_sel,
171         .pclk_sel_shift = FIRDA_CLK_SHIFT,
172         .recalc = &aux_clk_recalc,
173         .private_data = &firda_config,
174 };
175
176 /* clcd configurations */
177 static struct aux_clk_config clcd_config = {
178         .synth_reg = CLCD_CLK_SYNT,
179 };
180
181 /* clcd parents */
182 static struct pclk_info clcd_pclk_info[] = {
183         {
184                 .pclk = &pll1_clk,
185                 .pclk_mask = AUX_CLK_PLL1_MASK,
186                 .scalable = 1,
187         }, {
188                 .pclk = &pll3_48m_clk,
189                 .pclk_mask = AUX_CLK_PLL3_MASK,
190                 .scalable = 0,
191         },
192 };
193
194 /* clcd parent select structure */
195 static struct pclk_sel clcd_pclk_sel = {
196         .pclk_info = clcd_pclk_info,
197         .pclk_count = ARRAY_SIZE(clcd_pclk_info),
198         .pclk_sel_reg = PERIP_CLK_CFG,
199         .pclk_sel_mask = CLCD_CLK_MASK,
200 };
201
202 /* clcd clock */
203 static struct clk clcd_clk = {
204         .en_reg = PERIP1_CLK_ENB,
205         .en_reg_bit = CLCD_CLK_ENB,
206         .pclk_sel = &clcd_pclk_sel,
207         .pclk_sel_shift = CLCD_CLK_SHIFT,
208         .recalc = &aux_clk_recalc,
209         .private_data = &clcd_config,
210 };
211
212 /* gpt parents */
213 static struct pclk_info gpt_pclk_info[] = {
214         {
215                 .pclk = &pll1_clk,
216                 .pclk_mask = AUX_CLK_PLL1_MASK,
217                 .scalable = 1,
218         }, {
219                 .pclk = &pll3_48m_clk,
220                 .pclk_mask = AUX_CLK_PLL3_MASK,
221                 .scalable = 0,
222         },
223 };
224
225 /* gpt parent select structure */
226 static struct pclk_sel gpt_pclk_sel = {
227         .pclk_info = gpt_pclk_info,
228         .pclk_count = ARRAY_SIZE(gpt_pclk_info),
229         .pclk_sel_reg = PERIP_CLK_CFG,
230         .pclk_sel_mask = GPT_CLK_MASK,
231 };
232
233 /* gpt0_1 configurations */
234 static struct aux_clk_config gpt0_1_config = {
235         .synth_reg = PRSC1_CLK_CFG,
236 };
237
238 /* gpt0 ARM1 subsystem timer clock */
239 static struct clk gpt0_clk = {
240         .flags = ALWAYS_ENABLED,
241         .pclk_sel = &gpt_pclk_sel,
242         .pclk_sel_shift = GPT0_CLK_SHIFT,
243         .recalc = &gpt_clk_recalc,
244         .private_data = &gpt0_1_config,
245 };
246
247 /* gpt1 timer clock */
248 static struct clk gpt1_clk = {
249         .flags = ALWAYS_ENABLED,
250         .pclk_sel = &gpt_pclk_sel,
251         .pclk_sel_shift = GPT1_CLK_SHIFT,
252         .recalc = &gpt_clk_recalc,
253         .private_data = &gpt0_1_config,
254 };
255
256 /* gpt2 configurations */
257 static struct aux_clk_config gpt2_config = {
258         .synth_reg = PRSC2_CLK_CFG,
259 };
260
261 /* gpt2 timer clock */
262 static struct clk gpt2_clk = {
263         .en_reg = PERIP1_CLK_ENB,
264         .en_reg_bit = GPT2_CLK_ENB,
265         .pclk_sel = &gpt_pclk_sel,
266         .pclk_sel_shift = GPT2_CLK_SHIFT,
267         .recalc = &gpt_clk_recalc,
268         .private_data = &gpt2_config,
269 };
270
271 /* gpt3 configurations */
272 static struct aux_clk_config gpt3_config = {
273         .synth_reg = PRSC3_CLK_CFG,
274 };
275
276 /* gpt3 timer clock */
277 static struct clk gpt3_clk = {
278         .en_reg = PERIP1_CLK_ENB,
279         .en_reg_bit = GPT3_CLK_ENB,
280         .pclk_sel = &gpt_pclk_sel,
281         .pclk_sel_shift = GPT3_CLK_SHIFT,
282         .recalc = &gpt_clk_recalc,
283         .private_data = &gpt3_config,
284 };
285
286 /* clock derived from pll3 clk */
287 /* usbh0 clock */
288 static struct clk usbh0_clk = {
289         .pclk = &pll3_48m_clk,
290         .en_reg = PERIP1_CLK_ENB,
291         .en_reg_bit = USBH0_CLK_ENB,
292         .recalc = &follow_parent,
293 };
294
295 /* usbh1 clock */
296 static struct clk usbh1_clk = {
297         .pclk = &pll3_48m_clk,
298         .en_reg = PERIP1_CLK_ENB,
299         .en_reg_bit = USBH1_CLK_ENB,
300         .recalc = &follow_parent,
301 };
302
303 /* usbd clock */
304 static struct clk usbd_clk = {
305         .pclk = &pll3_48m_clk,
306         .en_reg = PERIP1_CLK_ENB,
307         .en_reg_bit = USBD_CLK_ENB,
308         .recalc = &follow_parent,
309 };
310
311 /* clock derived from ahb clk */
312 /* apb configuration structure */
313 static struct bus_clk_config apb_config = {
314         .reg = CORE_CLK_CFG,
315         .mask = HCLK_PCLK_RATIO_MASK,
316         .shift = HCLK_PCLK_RATIO_SHIFT,
317 };
318
319 /* apb clock */
320 static struct clk apb_clk = {
321         .flags = ALWAYS_ENABLED,
322         .pclk = &ahb_clk,
323         .recalc = &bus_clk_recalc,
324         .private_data = &apb_config,
325 };
326
327 /* i2c clock */
328 static struct clk i2c_clk = {
329         .pclk = &ahb_clk,
330         .en_reg = PERIP1_CLK_ENB,
331         .en_reg_bit = I2C_CLK_ENB,
332         .recalc = &follow_parent,
333 };
334
335 /* dma clock */
336 static struct clk dma_clk = {
337         .pclk = &ahb_clk,
338         .en_reg = PERIP1_CLK_ENB,
339         .en_reg_bit = DMA_CLK_ENB,
340         .recalc = &follow_parent,
341 };
342
343 /* jpeg clock */
344 static struct clk jpeg_clk = {
345         .pclk = &ahb_clk,
346         .en_reg = PERIP1_CLK_ENB,
347         .en_reg_bit = JPEG_CLK_ENB,
348         .recalc = &follow_parent,
349 };
350
351 /* gmac clock */
352 static struct clk gmac_clk = {
353         .pclk = &ahb_clk,
354         .en_reg = PERIP1_CLK_ENB,
355         .en_reg_bit = GMAC_CLK_ENB,
356         .recalc = &follow_parent,
357 };
358
359 /* smi clock */
360 static struct clk smi_clk = {
361         .pclk = &ahb_clk,
362         .en_reg = PERIP1_CLK_ENB,
363         .en_reg_bit = SMI_CLK_ENB,
364         .recalc = &follow_parent,
365 };
366
367 /* fsmc clock */
368 static struct clk fsmc_clk = {
369         .pclk = &ahb_clk,
370         .en_reg = PERIP1_CLK_ENB,
371         .en_reg_bit = FSMC_CLK_ENB,
372         .recalc = &follow_parent,
373 };
374
375 /* clock derived from apb clk */
376 /* adc clock */
377 static struct clk adc_clk = {
378         .pclk = &apb_clk,
379         .en_reg = PERIP1_CLK_ENB,
380         .en_reg_bit = ADC_CLK_ENB,
381         .recalc = &follow_parent,
382 };
383
384 /* ssp0 clock */
385 static struct clk ssp0_clk = {
386         .pclk = &apb_clk,
387         .en_reg = PERIP1_CLK_ENB,
388         .en_reg_bit = SSP0_CLK_ENB,
389         .recalc = &follow_parent,
390 };
391
392 /* ssp1 clock */
393 static struct clk ssp1_clk = {
394         .pclk = &apb_clk,
395         .en_reg = PERIP1_CLK_ENB,
396         .en_reg_bit = SSP1_CLK_ENB,
397         .recalc = &follow_parent,
398 };
399
400 /* ssp2 clock */
401 static struct clk ssp2_clk = {
402         .pclk = &apb_clk,
403         .en_reg = PERIP1_CLK_ENB,
404         .en_reg_bit = SSP2_CLK_ENB,
405         .recalc = &follow_parent,
406 };
407
408 /* gpio0 ARM subsystem clock */
409 static struct clk gpio0_clk = {
410         .flags = ALWAYS_ENABLED,
411         .pclk = &apb_clk,
412         .recalc = &follow_parent,
413 };
414
415 /* gpio1 clock */
416 static struct clk gpio1_clk = {
417         .pclk = &apb_clk,
418         .en_reg = PERIP1_CLK_ENB,
419         .en_reg_bit = GPIO1_CLK_ENB,
420         .recalc = &follow_parent,
421 };
422
423 /* gpio2 clock */
424 static struct clk gpio2_clk = {
425         .pclk = &apb_clk,
426         .en_reg = PERIP1_CLK_ENB,
427         .en_reg_bit = GPIO2_CLK_ENB,
428         .recalc = &follow_parent,
429 };
430
431 /* array of all spear 6xx clock lookups */
432 static struct clk_lookup spear_clk_lookups[] = {
433         /* root clks */
434         { .con_id = "osc_32k_clk",      .clk = &osc_32k_clk},
435         { .con_id = "osc_30m_clk",      .clk = &osc_30m_clk},
436         /* clock derived from 32 KHz os          clk */
437         { .dev_id = "rtc",              .clk = &rtc_clk},
438         /* clock derived from 30 MHz os          clk */
439         { .con_id = "pll1_clk",         .clk = &pll1_clk},
440         { .con_id = "pll3_48m_clk",     .clk = &pll3_48m_clk},
441         { .dev_id = "wdt",              .clk = &wdt_clk},
442         /* clock derived from pll1 clk */
443         { .con_id = "cpu_clk",          .clk = &cpu_clk},
444         { .con_id = "ahb_clk",          .clk = &ahb_clk},
445         { .dev_id = "uart0",            .clk = &uart0_clk},
446         { .dev_id = "uart1",            .clk = &uart1_clk},
447         { .dev_id = "firda",            .clk = &firda_clk},
448         { .dev_id = "clcd",             .clk = &clcd_clk},
449         { .dev_id = "gpt0",             .clk = &gpt0_clk},
450         { .dev_id = "gpt1",             .clk = &gpt1_clk},
451         { .dev_id = "gpt2",             .clk = &gpt2_clk},
452         { .dev_id = "gpt3",             .clk = &gpt3_clk},
453         /* clock derived from pll3 clk */
454         { .dev_id = "usbh0",            .clk = &usbh0_clk},
455         { .dev_id = "usbh1",            .clk = &usbh1_clk},
456         { .dev_id = "usbd",             .clk = &usbd_clk},
457         /* clock derived from ahb clk */
458         { .con_id = "apb_clk",          .clk = &apb_clk},
459         { .dev_id = "i2c",              .clk = &i2c_clk},
460         { .dev_id = "dma",              .clk = &dma_clk},
461         { .dev_id = "jpeg",             .clk = &jpeg_clk},
462         { .dev_id = "gmac",             .clk = &gmac_clk},
463         { .dev_id = "smi",              .clk = &smi_clk},
464         { .dev_id = "fsmc",             .clk = &fsmc_clk},
465         /* clock derived from apb clk */
466         { .dev_id = "adc",              .clk = &adc_clk},
467         { .dev_id = "ssp0",             .clk = &ssp0_clk},
468         { .dev_id = "ssp1",             .clk = &ssp1_clk},
469         { .dev_id = "ssp2",             .clk = &ssp2_clk},
470         { .dev_id = "gpio0",            .clk = &gpio0_clk},
471         { .dev_id = "gpio1",            .clk = &gpio1_clk},
472         { .dev_id = "gpio2",            .clk = &gpio2_clk},
473 };
474
475 void __init clk_init(void)
476 {
477         int i;
478
479         for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
480                 clk_register(&spear_clk_lookups[i]);
481
482         recalc_root_clocks();
483 }