2 * arch/arm/mach-spear3xx/clock.c
4 * SPEAr3xx machines clock framework source file
6 * Copyright (C) 2009 ST Microelectronics
7 * Viresh Kumar<viresh.kumar@st.com>
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.
14 #include <linux/init.h>
15 #include <linux/kernel.h>
16 #include <mach/misc_regs.h>
17 #include <plat/clock.h>
20 /* 32 KHz oscillator clock */
21 static struct clk osc_32k_clk
= {
22 .flags
= ALWAYS_ENABLED
,
26 /* 24 MHz oscillator clock */
27 static struct clk osc_24m_clk
= {
28 .flags
= ALWAYS_ENABLED
,
32 /* clock derived from 32 KHz osc clk */
34 static struct clk rtc_clk
= {
36 .en_reg
= PERIP1_CLK_ENB
,
37 .en_reg_bit
= RTC_CLK_ENB
,
38 .recalc
= &follow_parent
,
41 /* clock derived from 24 MHz osc clk */
42 /* pll masks structure */
43 static struct pll_clk_masks pll1_masks
= {
44 .mode_mask
= PLL_MODE_MASK
,
45 .mode_shift
= PLL_MODE_SHIFT
,
46 .norm_fdbk_m_mask
= PLL_NORM_FDBK_M_MASK
,
47 .norm_fdbk_m_shift
= PLL_NORM_FDBK_M_SHIFT
,
48 .dith_fdbk_m_mask
= PLL_DITH_FDBK_M_MASK
,
49 .dith_fdbk_m_shift
= PLL_DITH_FDBK_M_SHIFT
,
50 .div_p_mask
= PLL_DIV_P_MASK
,
51 .div_p_shift
= PLL_DIV_P_SHIFT
,
52 .div_n_mask
= PLL_DIV_N_MASK
,
53 .div_n_shift
= PLL_DIV_N_SHIFT
,
56 /* pll1 configuration structure */
57 static struct pll_clk_config pll1_config
= {
64 static struct clk pll1_clk
= {
67 .en_reg_bit
= PLL_ENABLE
,
68 .recalc
= &pll_clk_recalc
,
69 .private_data
= &pll1_config
,
72 /* PLL3 48 MHz clock */
73 static struct clk pll3_48m_clk
= {
74 .flags
= ALWAYS_ENABLED
,
79 /* watch dog timer clock */
80 static struct clk wdt_clk
= {
81 .flags
= ALWAYS_ENABLED
,
83 .recalc
= &follow_parent
,
86 /* clock derived from pll1 clk */
88 static struct clk cpu_clk
= {
89 .flags
= ALWAYS_ENABLED
,
91 .recalc
= &follow_parent
,
94 /* ahb masks structure */
95 static struct bus_clk_masks ahb_masks
= {
96 .mask
= PLL_HCLK_RATIO_MASK
,
97 .shift
= PLL_HCLK_RATIO_SHIFT
,
100 /* ahb configuration structure */
101 static struct bus_clk_config ahb_config
= {
107 static struct clk ahb_clk
= {
108 .flags
= ALWAYS_ENABLED
,
110 .recalc
= &bus_clk_recalc
,
111 .private_data
= &ahb_config
,
114 /* auxiliary synthesizers masks */
115 static struct aux_clk_masks aux_masks
= {
116 .eq_sel_mask
= AUX_EQ_SEL_MASK
,
117 .eq_sel_shift
= AUX_EQ_SEL_SHIFT
,
118 .eq1_mask
= AUX_EQ1_SEL
,
119 .eq2_mask
= AUX_EQ2_SEL
,
120 .xscale_sel_mask
= AUX_XSCALE_MASK
,
121 .xscale_sel_shift
= AUX_XSCALE_SHIFT
,
122 .yscale_sel_mask
= AUX_YSCALE_MASK
,
123 .yscale_sel_shift
= AUX_YSCALE_SHIFT
,
126 /* uart configurations */
127 static struct aux_clk_config uart_config
= {
128 .synth_reg
= UART_CLK_SYNT
,
133 static struct pclk_info uart_pclk_info
[] = {
136 .pclk_mask
= AUX_CLK_PLL1_MASK
,
139 .pclk
= &pll3_48m_clk
,
140 .pclk_mask
= AUX_CLK_PLL3_MASK
,
145 /* uart parent select structure */
146 static struct pclk_sel uart_pclk_sel
= {
147 .pclk_info
= uart_pclk_info
,
148 .pclk_count
= ARRAY_SIZE(uart_pclk_info
),
149 .pclk_sel_reg
= PERIP_CLK_CFG
,
150 .pclk_sel_mask
= UART_CLK_MASK
,
154 static struct clk uart_clk
= {
155 .en_reg
= PERIP1_CLK_ENB
,
156 .en_reg_bit
= UART_CLK_ENB
,
157 .pclk_sel
= &uart_pclk_sel
,
158 .pclk_sel_shift
= UART_CLK_SHIFT
,
159 .recalc
= &aux_clk_recalc
,
160 .private_data
= &uart_config
,
163 /* firda configurations */
164 static struct aux_clk_config firda_config
= {
165 .synth_reg
= FIRDA_CLK_SYNT
,
170 static struct pclk_info firda_pclk_info
[] = {
173 .pclk_mask
= AUX_CLK_PLL1_MASK
,
176 .pclk
= &pll3_48m_clk
,
177 .pclk_mask
= AUX_CLK_PLL3_MASK
,
182 /* firda parent select structure */
183 static struct pclk_sel firda_pclk_sel
= {
184 .pclk_info
= firda_pclk_info
,
185 .pclk_count
= ARRAY_SIZE(firda_pclk_info
),
186 .pclk_sel_reg
= PERIP_CLK_CFG
,
187 .pclk_sel_mask
= FIRDA_CLK_MASK
,
191 static struct clk firda_clk
= {
192 .en_reg
= PERIP1_CLK_ENB
,
193 .en_reg_bit
= FIRDA_CLK_ENB
,
194 .pclk_sel
= &firda_pclk_sel
,
195 .pclk_sel_shift
= FIRDA_CLK_SHIFT
,
196 .recalc
= &aux_clk_recalc
,
197 .private_data
= &firda_config
,
201 static struct pclk_info gpt_pclk_info
[] = {
204 .pclk_mask
= AUX_CLK_PLL1_MASK
,
207 .pclk
= &pll3_48m_clk
,
208 .pclk_mask
= AUX_CLK_PLL3_MASK
,
213 /* gpt parent select structure */
214 static struct pclk_sel gpt_pclk_sel
= {
215 .pclk_info
= gpt_pclk_info
,
216 .pclk_count
= ARRAY_SIZE(gpt_pclk_info
),
217 .pclk_sel_reg
= PERIP_CLK_CFG
,
218 .pclk_sel_mask
= GPT_CLK_MASK
,
221 /* gpt synthesizer masks */
222 static struct gpt_clk_masks gpt_masks
= {
223 .mscale_sel_mask
= GPT_MSCALE_MASK
,
224 .mscale_sel_shift
= GPT_MSCALE_SHIFT
,
225 .nscale_sel_mask
= GPT_NSCALE_MASK
,
226 .nscale_sel_shift
= GPT_NSCALE_SHIFT
,
229 /* gpt0 configurations */
230 static struct gpt_clk_config gpt0_config
= {
231 .synth_reg
= PRSC1_CLK_CFG
,
235 /* gpt0 timer clock */
236 static struct clk gpt0_clk
= {
237 .flags
= ALWAYS_ENABLED
,
238 .pclk_sel
= &gpt_pclk_sel
,
239 .pclk_sel_shift
= GPT0_CLK_SHIFT
,
240 .recalc
= &gpt_clk_recalc
,
241 .private_data
= &gpt0_config
,
244 /* gpt1 configurations */
245 static struct gpt_clk_config gpt1_config
= {
246 .synth_reg
= PRSC2_CLK_CFG
,
250 /* gpt1 timer clock */
251 static struct clk gpt1_clk
= {
252 .en_reg
= PERIP1_CLK_ENB
,
253 .en_reg_bit
= GPT1_CLK_ENB
,
254 .pclk_sel
= &gpt_pclk_sel
,
255 .pclk_sel_shift
= GPT1_CLK_SHIFT
,
256 .recalc
= &gpt_clk_recalc
,
257 .private_data
= &gpt1_config
,
260 /* gpt2 configurations */
261 static struct gpt_clk_config gpt2_config
= {
262 .synth_reg
= PRSC3_CLK_CFG
,
266 /* gpt2 timer clock */
267 static struct clk gpt2_clk
= {
268 .en_reg
= PERIP1_CLK_ENB
,
269 .en_reg_bit
= GPT2_CLK_ENB
,
270 .pclk_sel
= &gpt_pclk_sel
,
271 .pclk_sel_shift
= GPT2_CLK_SHIFT
,
272 .recalc
= &gpt_clk_recalc
,
273 .private_data
= &gpt2_config
,
276 /* clock derived from pll3 clk */
278 static struct clk usbh_clk
= {
279 .pclk
= &pll3_48m_clk
,
280 .en_reg
= PERIP1_CLK_ENB
,
281 .en_reg_bit
= USBH_CLK_ENB
,
282 .recalc
= &follow_parent
,
286 static struct clk usbd_clk
= {
287 .pclk
= &pll3_48m_clk
,
288 .en_reg
= PERIP1_CLK_ENB
,
289 .en_reg_bit
= USBD_CLK_ENB
,
290 .recalc
= &follow_parent
,
294 static struct clk clcd_clk
= {
295 .flags
= ALWAYS_ENABLED
,
296 .pclk
= &pll3_48m_clk
,
297 .recalc
= &follow_parent
,
300 /* clock derived from ahb clk */
301 /* apb masks structure */
302 static struct bus_clk_masks apb_masks
= {
303 .mask
= HCLK_PCLK_RATIO_MASK
,
304 .shift
= HCLK_PCLK_RATIO_SHIFT
,
307 /* apb configuration structure */
308 static struct bus_clk_config apb_config
= {
314 static struct clk apb_clk
= {
315 .flags
= ALWAYS_ENABLED
,
317 .recalc
= &bus_clk_recalc
,
318 .private_data
= &apb_config
,
322 static struct clk i2c_clk
= {
324 .en_reg
= PERIP1_CLK_ENB
,
325 .en_reg_bit
= I2C_CLK_ENB
,
326 .recalc
= &follow_parent
,
330 static struct clk dma_clk
= {
332 .en_reg
= PERIP1_CLK_ENB
,
333 .en_reg_bit
= DMA_CLK_ENB
,
334 .recalc
= &follow_parent
,
338 static struct clk jpeg_clk
= {
340 .en_reg
= PERIP1_CLK_ENB
,
341 .en_reg_bit
= JPEG_CLK_ENB
,
342 .recalc
= &follow_parent
,
346 static struct clk gmac_clk
= {
348 .en_reg
= PERIP1_CLK_ENB
,
349 .en_reg_bit
= GMAC_CLK_ENB
,
350 .recalc
= &follow_parent
,
354 static struct clk smi_clk
= {
356 .en_reg
= PERIP1_CLK_ENB
,
357 .en_reg_bit
= SMI_CLK_ENB
,
358 .recalc
= &follow_parent
,
362 static struct clk c3_clk
= {
364 .en_reg
= PERIP1_CLK_ENB
,
365 .en_reg_bit
= C3_CLK_ENB
,
366 .recalc
= &follow_parent
,
369 /* clock derived from apb clk */
371 static struct clk adc_clk
= {
373 .en_reg
= PERIP1_CLK_ENB
,
374 .en_reg_bit
= ADC_CLK_ENB
,
375 .recalc
= &follow_parent
,
379 static struct clk ssp_clk
= {
381 .en_reg
= PERIP1_CLK_ENB
,
382 .en_reg_bit
= SSP_CLK_ENB
,
383 .recalc
= &follow_parent
,
387 static struct clk gpio_clk
= {
389 .en_reg
= PERIP1_CLK_ENB
,
390 .en_reg_bit
= GPIO_CLK_ENB
,
391 .recalc
= &follow_parent
,
394 static struct clk dummy_apb_pclk
;
396 /* array of all spear 3xx clock lookups */
397 static struct clk_lookup spear_clk_lookups
[] = {
398 { .con_id
= "apb_pclk", .clk
= &dummy_apb_pclk
},
400 { .con_id
= "osc_32k_clk", .clk
= &osc_32k_clk
},
401 { .con_id
= "osc_24m_clk", .clk
= &osc_24m_clk
},
402 /* clock derived from 32 KHz osc clk */
403 { .dev_id
= "rtc", .clk
= &rtc_clk
},
404 /* clock derived from 24 MHz osc clk */
405 { .con_id
= "pll1_clk", .clk
= &pll1_clk
},
406 { .con_id
= "pll3_48m_clk", .clk
= &pll3_48m_clk
},
407 { .dev_id
= "wdt", .clk
= &wdt_clk
},
408 /* clock derived from pll1 clk */
409 { .con_id
= "cpu_clk", .clk
= &cpu_clk
},
410 { .con_id
= "ahb_clk", .clk
= &ahb_clk
},
411 { .dev_id
= "uart", .clk
= &uart_clk
},
412 { .dev_id
= "firda", .clk
= &firda_clk
},
413 { .dev_id
= "gpt0", .clk
= &gpt0_clk
},
414 { .dev_id
= "gpt1", .clk
= &gpt1_clk
},
415 { .dev_id
= "gpt2", .clk
= &gpt2_clk
},
416 /* clock derived from pll3 clk */
417 { .dev_id
= "usbh", .clk
= &usbh_clk
},
418 { .dev_id
= "usbd", .clk
= &usbd_clk
},
419 { .dev_id
= "clcd", .clk
= &clcd_clk
},
420 /* clock derived from ahb clk */
421 { .con_id
= "apb_clk", .clk
= &apb_clk
},
422 { .dev_id
= "i2c", .clk
= &i2c_clk
},
423 { .dev_id
= "dma", .clk
= &dma_clk
},
424 { .dev_id
= "jpeg", .clk
= &jpeg_clk
},
425 { .dev_id
= "gmac", .clk
= &gmac_clk
},
426 { .dev_id
= "smi", .clk
= &smi_clk
},
427 { .dev_id
= "c3", .clk
= &c3_clk
},
428 /* clock derived from apb clk */
429 { .dev_id
= "adc", .clk
= &adc_clk
},
430 { .dev_id
= "ssp", .clk
= &ssp_clk
},
431 { .dev_id
= "gpio", .clk
= &gpio_clk
},
434 void __init
clk_init(void)
438 for (i
= 0; i
< ARRAY_SIZE(spear_clk_lookups
); i
++)
439 clk_register(&spear_clk_lookups
[i
]);
441 recalc_root_clocks();