4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
5 * Vaibhav Hiremath <hvaibhav@ti.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation version 2.
11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <linux/kernel.h>
18 #include <linux/list.h>
19 #include <linux/clk.h>
20 #include <plat/clkdev_omap.h>
21 #include <plat/am33xx.h>
28 #include "cm-regbits-33xx.h"
31 /* Maximum DPLL multiplier, divider values for AM33XX */
32 #define AM33XX_MAX_DPLL_MULT 2047
33 #define AM33XX_MAX_DPLL_DIV 128
35 /* Modulemode control */
36 #define AM33XX_MODULEMODE_HWCTRL 0
37 #define AM33XX_MODULEMODE_SWCTRL 1
39 /* TRM ERRATA: Timer 3 & 6 default parent (TCLKIN) may not be always
40 * physically present, in such a case HWMOD enabling of
41 * clock would be failure with default parent. And timer
42 * probe thinks clock is already enabled, this leads to
43 * crash upon accessing timer 3 & 6 registers in probe.
44 * Fix by setting parent of both these timers to master
47 static inline void am33xx_init_timer_parent(struct clk
*clk
)
49 omap2_clksel_set_parent(clk
, clk
->parent
);
55 static struct clk clk_32768_ck
= {
56 .name
= "clk_32768_ck",
57 .clkdm_name
= "l4_rtc_clkdm",
62 /* On-Chip 32KHz RC OSC */
63 static struct clk clk_rc32k_ck
= {
64 .name
= "clk_rc32k_ck",
69 /* Crystal input clks */
70 static struct clk virt_24000000_ck
= {
71 .name
= "virt_24000000_ck",
76 static struct clk virt_25000000_ck
= {
77 .name
= "virt_25000000_ck",
82 /* Oscillator clock */
83 /* 19.2, 24, 25 or 26 MHz */
84 static const struct clksel sys_clkin_sel
[] = {
85 { .parent
= &virt_19200000_ck
, .rates
= div_1_0_rates
},
86 { .parent
= &virt_24000000_ck
, .rates
= div_1_1_rates
},
87 { .parent
= &virt_25000000_ck
, .rates
= div_1_2_rates
},
88 { .parent
= &virt_26000000_ck
, .rates
= div_1_3_rates
},
92 /* External clock - 12 MHz */
93 static struct clk tclkin_ck
= {
100 * sys_clk in: input to the dpll and also used as funtional clock for,
101 * adc_tsc, smartreflex0-1, timer1-7, mcasp0-1, dcan0-1, cefuse
104 static struct clk sys_clkin_ck
= {
105 .name
= "sys_clkin_ck",
106 .parent
= &virt_24000000_ck
,
107 .init
= &omap2_init_clksel_parent
,
108 .clksel_reg
= AM33XX_CTRL_REGADDR(AM33XX_CONTROL_STATUS
),
109 .clksel_mask
= AM33XX_CONTROL_STATUS_SYSBOOT1_MASK
,
110 .clksel
= sys_clkin_sel
,
112 .recalc
= &omap2_clksel_recalc
,
116 static struct dpll_data dpll_core_dd
= {
117 .mult_div1_reg
= AM33XX_CM_CLKSEL_DPLL_CORE
,
118 .clk_bypass
= &sys_clkin_ck
,
119 .clk_ref
= &sys_clkin_ck
,
120 .control_reg
= AM33XX_CM_CLKMODE_DPLL_CORE
,
121 .modes
= (1 << DPLL_LOW_POWER_BYPASS
) | (1 << DPLL_LOCKED
),
122 .idlest_reg
= AM33XX_CM_IDLEST_DPLL_CORE
,
123 .mult_mask
= AM33XX_DPLL_MULT_MASK
,
124 .div1_mask
= AM33XX_DPLL_DIV_MASK
,
125 .enable_mask
= AM33XX_DPLL_EN_MASK
,
126 .idlest_mask
= AM33XX_ST_DPLL_CLK_MASK
,
127 .max_multiplier
= AM33XX_MAX_DPLL_MULT
,
128 .max_divider
= AM33XX_MAX_DPLL_DIV
,
132 /* CLKDCOLDO output */
133 static struct clk dpll_core_ck
= {
134 .name
= "dpll_core_ck",
135 .parent
= &sys_clkin_ck
,
136 .dpll_data
= &dpll_core_dd
,
137 .init
= &omap2_init_dpll_parent
,
138 .ops
= &clkops_omap3_core_dpll_ops
,
139 .recalc
= &omap3_dpll_recalc
,
142 static struct clk dpll_core_x2_ck
= {
143 .name
= "dpll_core_x2_ck",
144 .parent
= &dpll_core_ck
,
145 .flags
= CLOCK_CLKOUTX2
,
147 .recalc
= &omap3_clkoutx2_recalc
,
151 static const struct clksel dpll_core_m4_div
[] = {
152 { .parent
= &dpll_core_x2_ck
, .rates
= div31_1to31_rates
},
156 static struct clk dpll_core_m4_ck
= {
157 .name
= "dpll_core_m4_ck",
158 .parent
= &dpll_core_x2_ck
,
159 .init
= &omap2_init_clksel_parent
,
160 .clksel
= dpll_core_m4_div
,
161 .clksel_reg
= AM33XX_CM_DIV_M4_DPLL_CORE
,
162 .clksel_mask
= AM33XX_HSDIVIDER_CLKOUT1_DIV_MASK
,
164 .recalc
= &omap2_clksel_recalc
,
165 .round_rate
= &omap2_clksel_round_rate
,
166 .set_rate
= &omap2_clksel_set_rate
,
169 static const struct clksel dpll_core_m5_div
[] = {
170 { .parent
= &dpll_core_x2_ck
, .rates
= div31_1to31_rates
},
174 static struct clk dpll_core_m5_ck
= {
175 .name
= "dpll_core_m5_ck",
176 .parent
= &dpll_core_x2_ck
,
177 .init
= &omap2_init_clksel_parent
,
178 .clksel
= dpll_core_m5_div
,
179 .clksel_reg
= AM33XX_CM_DIV_M5_DPLL_CORE
,
180 .clksel_mask
= AM33XX_HSDIVIDER_CLKOUT2_DIV_MASK
,
182 .recalc
= &omap2_clksel_recalc
,
183 .round_rate
= &omap2_clksel_round_rate
,
184 .set_rate
= &omap2_clksel_set_rate
,
187 static const struct clksel dpll_core_m6_div
[] = {
188 { .parent
= &dpll_core_x2_ck
, .rates
= div31_1to31_rates
},
192 static struct clk dpll_core_m6_ck
= {
193 .name
= "dpll_core_m6_ck",
194 .parent
= &dpll_core_x2_ck
,
195 .init
= &omap2_init_clksel_parent
,
196 .clksel
= dpll_core_m6_div
,
197 .clksel_reg
= AM33XX_CM_DIV_M6_DPLL_CORE
,
198 .clksel_mask
= AM33XX_HSDIVIDER_CLKOUT3_DIV_MASK
,
200 .recalc
= &omap2_clksel_recalc
,
201 .round_rate
= &omap2_clksel_round_rate
,
202 .set_rate
= &omap2_clksel_set_rate
,
206 static struct dpll_data dpll_mpu_dd
= {
207 .mult_div1_reg
= AM33XX_CM_CLKSEL_DPLL_MPU
,
208 .clk_bypass
= &sys_clkin_ck
,
209 .clk_ref
= &sys_clkin_ck
,
210 .control_reg
= AM33XX_CM_CLKMODE_DPLL_MPU
,
211 .modes
= (1 << DPLL_LOW_POWER_BYPASS
) | (1 << DPLL_LOCKED
),
212 .idlest_reg
= AM33XX_CM_IDLEST_DPLL_MPU
,
213 .mult_mask
= AM33XX_DPLL_MULT_MASK
,
214 .div1_mask
= AM33XX_DPLL_DIV_MASK
,
215 .enable_mask
= AM33XX_DPLL_EN_MASK
,
216 .idlest_mask
= AM33XX_ST_DPLL_CLK_MASK
,
217 .max_multiplier
= AM33XX_MAX_DPLL_MULT
,
218 .max_divider
= AM33XX_MAX_DPLL_DIV
,
222 /* CLKOUT: fdpll/M2 */
223 static struct clk dpll_mpu_ck
= {
224 .name
= "dpll_mpu_ck",
225 .parent
= &sys_clkin_ck
,
226 .dpll_data
= &dpll_mpu_dd
,
227 .init
= &omap2_init_dpll_parent
,
228 .ops
= &clkops_omap3_noncore_dpll_ops
,
229 .recalc
= &omap3_dpll_recalc
,
230 .round_rate
= &omap2_dpll_round_rate
,
231 .set_rate
= &omap3_noncore_dpll_set_rate
,
235 * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
238 static const struct clksel dpll_mpu_m2_div
[] = {
239 { .parent
= &dpll_mpu_ck
, .rates
= div31_1to31_rates
},
243 static struct clk dpll_mpu_m2_ck
= {
244 .name
= "dpll_mpu_m2_ck",
245 .clkdm_name
= "mpu_clkdm",
246 .parent
= &dpll_mpu_ck
,
247 .clksel
= dpll_mpu_m2_div
,
248 .clksel_reg
= AM33XX_CM_DIV_M2_DPLL_MPU
,
249 .clksel_mask
= AM33XX_DPLL_CLKOUT_DIV_MASK
,
251 .recalc
= &omap2_clksel_recalc
,
252 .round_rate
= &omap2_clksel_round_rate
,
253 .set_rate
= &omap2_clksel_set_rate
,
257 static struct dpll_data dpll_ddr_dd
= {
258 .mult_div1_reg
= AM33XX_CM_CLKSEL_DPLL_DDR
,
259 .clk_bypass
= &sys_clkin_ck
,
260 .clk_ref
= &sys_clkin_ck
,
261 .control_reg
= AM33XX_CM_CLKMODE_DPLL_DDR
,
262 .modes
= (1 << DPLL_LOW_POWER_BYPASS
) | (1 << DPLL_LOCKED
),
263 .idlest_reg
= AM33XX_CM_IDLEST_DPLL_DDR
,
264 .mult_mask
= AM33XX_DPLL_MULT_MASK
,
265 .div1_mask
= AM33XX_DPLL_DIV_MASK
,
266 .enable_mask
= AM33XX_DPLL_EN_MASK
,
267 .idlest_mask
= AM33XX_ST_DPLL_CLK_MASK
,
268 .max_multiplier
= AM33XX_MAX_DPLL_MULT
,
269 .max_divider
= AM33XX_MAX_DPLL_DIV
,
273 /* CLKOUT: fdpll/M2 */
274 static struct clk dpll_ddr_ck
= {
275 .name
= "dpll_ddr_ck",
276 .parent
= &sys_clkin_ck
,
277 .dpll_data
= &dpll_ddr_dd
,
278 .init
= &omap2_init_dpll_parent
,
280 .recalc
= &omap3_dpll_recalc
,
284 * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
287 static const struct clksel dpll_ddr_m2_div
[] = {
288 { .parent
= &dpll_ddr_ck
, .rates
= div31_1to31_rates
},
292 static struct clk dpll_ddr_m2_ck
= {
293 .name
= "dpll_ddr_m2_ck",
294 .parent
= &dpll_ddr_ck
,
295 .clksel
= dpll_ddr_m2_div
,
296 .clksel_reg
= AM33XX_CM_DIV_M2_DPLL_DDR
,
297 .clksel_mask
= AM33XX_DPLL_CLKOUT_DIV_MASK
,
299 .recalc
= &omap2_clksel_recalc
,
300 .round_rate
= &omap2_clksel_round_rate
,
301 .set_rate
= &omap2_clksel_set_rate
,
304 /* emif_fck functional clock */
305 static struct clk dpll_ddr_m2_div2_ck
= {
306 .name
= "dpll_ddr_m2_div2_ck",
307 .clkdm_name
= "l3_clkdm",
308 .parent
= &dpll_ddr_m2_ck
,
311 .recalc
= &omap_fixed_divisor_recalc
,
315 static struct dpll_data dpll_disp_dd
= {
316 .mult_div1_reg
= AM33XX_CM_CLKSEL_DPLL_DISP
,
317 .clk_bypass
= &sys_clkin_ck
,
318 .clk_ref
= &sys_clkin_ck
,
319 .control_reg
= AM33XX_CM_CLKMODE_DPLL_DISP
,
320 .modes
= (1 << DPLL_LOW_POWER_BYPASS
) | (1 << DPLL_LOCKED
),
321 .idlest_reg
= AM33XX_CM_IDLEST_DPLL_DISP
,
322 .mult_mask
= AM33XX_DPLL_MULT_MASK
,
323 .div1_mask
= AM33XX_DPLL_DIV_MASK
,
324 .enable_mask
= AM33XX_DPLL_EN_MASK
,
325 .idlest_mask
= AM33XX_ST_DPLL_CLK_MASK
,
326 .max_multiplier
= AM33XX_MAX_DPLL_MULT
,
327 .max_divider
= AM33XX_MAX_DPLL_DIV
,
331 /* CLKOUT: fdpll/M2 */
332 static struct clk dpll_disp_ck
= {
333 .name
= "dpll_disp_ck",
334 .parent
= &sys_clkin_ck
,
335 .dpll_data
= &dpll_disp_dd
,
336 .init
= &omap2_init_dpll_parent
,
338 .recalc
= &omap3_dpll_recalc
,
339 .round_rate
= &omap2_dpll_round_rate
,
340 .set_rate
= &omap3_noncore_dpll_set_rate
,
344 * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
347 static const struct clksel dpll_disp_m2_div
[] = {
348 { .parent
= &dpll_disp_ck
, .rates
= div31_1to31_rates
},
352 static struct clk dpll_disp_m2_ck
= {
353 .name
= "dpll_disp_m2_ck",
354 .parent
= &dpll_disp_ck
,
355 .clksel
= dpll_disp_m2_div
,
356 .clksel_reg
= AM33XX_CM_DIV_M2_DPLL_DISP
,
357 .clksel_mask
= AM33XX_DPLL_CLKOUT_DIV_MASK
,
359 .recalc
= &omap2_clksel_recalc
,
360 .round_rate
= &omap2_clksel_round_rate
,
361 .set_rate
= &omap2_clksel_set_rate
,
365 static struct dpll_data dpll_per_dd
= {
366 .mult_div1_reg
= AM33XX_CM_CLKSEL_DPLL_PERIPH
,
367 .clk_bypass
= &sys_clkin_ck
,
368 .clk_ref
= &sys_clkin_ck
,
369 .control_reg
= AM33XX_CM_CLKMODE_DPLL_PER
,
370 .modes
= (1 << DPLL_LOW_POWER_BYPASS
) | (1 << DPLL_LOCKED
),
371 .idlest_reg
= AM33XX_CM_IDLEST_DPLL_PER
,
372 .mult_mask
= AM33XX_DPLL_MULT_PERIPH_MASK
,
373 .div1_mask
= AM33XX_DPLL_PER_DIV_MASK
,
374 .enable_mask
= AM33XX_DPLL_EN_MASK
,
375 .idlest_mask
= AM33XX_ST_DPLL_CLK_MASK
,
376 .max_multiplier
= AM33XX_MAX_DPLL_MULT
,
377 .max_divider
= AM33XX_MAX_DPLL_DIV
,
379 .flags
= DPLL_J_TYPE
,
383 static struct clk dpll_per_ck
= {
384 .name
= "dpll_per_ck",
385 .parent
= &sys_clkin_ck
,
386 .dpll_data
= &dpll_per_dd
,
387 .init
= &omap2_init_dpll_parent
,
389 .recalc
= &omap3_dpll_recalc
,
390 .round_rate
= &omap2_dpll_round_rate
,
391 .set_rate
= &omap3_noncore_dpll_set_rate
,
394 /* CLKOUT: fdpll/M2 */
395 static const struct clksel dpll_per_m2_div
[] = {
396 { .parent
= &dpll_per_ck
, .rates
= div31_1to31_rates
},
400 static struct clk dpll_per_m2_ck
= {
401 .name
= "dpll_per_m2_ck",
402 .parent
= &dpll_per_ck
,
403 .clksel
= dpll_per_m2_div
,
404 .clksel_reg
= AM33XX_CM_DIV_M2_DPLL_PER
,
405 .clksel_mask
= AM33XX_DPLL_CLKOUT_DIV_MASK
,
407 .recalc
= &omap2_clksel_recalc
,
408 .round_rate
= &omap2_clksel_round_rate
,
409 .set_rate
= &omap2_clksel_set_rate
,
412 static struct clk dpll_per_m2_div4_wkupdm_ck
= {
413 .name
= "dpll_per_m2_div4_wkupdm_ck",
414 .clkdm_name
= "l4_wkup_clkdm",
415 .parent
= &dpll_per_m2_ck
,
418 .recalc
= &omap_fixed_divisor_recalc
,
421 static struct clk dpll_per_m2_div4_ck
= {
422 .name
= "dpll_per_m2_div4_ck",
423 .clkdm_name
= "l4ls_clkdm",
424 .parent
= &dpll_per_m2_ck
,
427 .recalc
= &omap_fixed_divisor_recalc
,
430 static struct clk l3_gclk
= {
432 .clkdm_name
= "l3_clkdm",
433 .parent
= &dpll_core_m4_ck
,
435 .recalc
= &followparent_recalc
,
438 static struct clk dpll_core_m4_div2_ck
= {
439 .name
= "dpll_core_m4_div2_ck",
440 .clkdm_name
= "l4_wkup_clkdm",
441 .parent
= &dpll_core_m4_ck
,
444 .recalc
= &omap_fixed_divisor_recalc
,
447 static struct clk l4_rtc_gclk
= {
448 .name
= "l4_rtc_gclk",
449 .parent
= &dpll_core_m4_ck
,
452 .recalc
= &omap_fixed_divisor_recalc
,
455 static struct clk clk_24mhz
= {
457 .parent
= &dpll_per_m2_ck
,
460 .recalc
= &omap_fixed_divisor_recalc
,
464 * Below clock nodes describes clockdomains derived out
467 static struct clk l4hs_gclk
= {
469 .clkdm_name
= "l4hs_clkdm",
470 .parent
= &dpll_core_m4_ck
,
472 .recalc
= &followparent_recalc
,
475 static struct clk l3s_gclk
= {
477 .clkdm_name
= "l3s_clkdm",
478 .parent
= &dpll_core_m4_div2_ck
,
480 .recalc
= &followparent_recalc
,
483 static struct clk l4fw_gclk
= {
485 .clkdm_name
= "l4fw_clkdm",
486 .parent
= &dpll_core_m4_div2_ck
,
488 .recalc
= &followparent_recalc
,
491 static struct clk l4ls_gclk
= {
493 .clkdm_name
= "l4ls_clkdm",
494 .parent
= &dpll_core_m4_div2_ck
,
496 .recalc
= &followparent_recalc
,
499 static struct clk sysclk_div_ck
= {
500 .name
= "sysclk_div_ck",
501 .parent
= &dpll_core_m4_ck
,
503 .recalc
= &followparent_recalc
,
507 * In order to match the clock domain with hwmod clockdomain entry,
508 * separate clock nodes is required for the modules which are
509 * directly getting their funtioncal clock from sys_clkin.
511 static struct clk adc_tsc_fck
= {
512 .name
= "adc_tsc_fck",
513 .clkdm_name
= "l4_wkup_clkdm",
514 .parent
= &sys_clkin_ck
,
516 .recalc
= &followparent_recalc
,
519 static struct clk dcan0_fck
= {
521 .clkdm_name
= "l4ls_clkdm",
522 .parent
= &sys_clkin_ck
,
524 .recalc
= &followparent_recalc
,
527 static struct clk dcan1_fck
= {
529 .clkdm_name
= "l4ls_clkdm",
530 .parent
= &sys_clkin_ck
,
532 .recalc
= &followparent_recalc
,
535 static struct clk mcasp0_fck
= {
536 .name
= "mcasp0_fck",
537 .clkdm_name
= "l3s_clkdm",
538 .parent
= &sys_clkin_ck
,
540 .recalc
= &followparent_recalc
,
543 static struct clk mcasp1_fck
= {
544 .name
= "mcasp1_fck",
545 .clkdm_name
= "l3s_clkdm",
546 .parent
= &sys_clkin_ck
,
548 .recalc
= &followparent_recalc
,
551 static struct clk smartreflex0_fck
= {
552 .name
= "smartreflex0_fck",
553 .clkdm_name
= "l4_wkup_clkdm",
554 .parent
= &sys_clkin_ck
,
556 .recalc
= &followparent_recalc
,
559 static struct clk smartreflex1_fck
= {
560 .name
= "smartreflex1_fck",
561 .clkdm_name
= "l4_wkup_clkdm",
562 .parent
= &sys_clkin_ck
,
564 .recalc
= &followparent_recalc
,
568 * Modules clock nodes
570 * The following clock leaf nodes are added for the moment because:
572 * - hwmod data is not present for these modules, either hwmod
573 * control is not required or its not populated.
574 * - Driver code is not yet migrated to use hwmod/runtime pm
575 * - Modules outside kernel access (to disable them by default)
580 * - usbotg_fck (its additional clock and not really a modulemode)
583 static struct clk debugss_ick
= {
584 .name
= "debugss_ick",
585 .clkdm_name
= "l3_aon_clkdm",
586 .parent
= &dpll_core_m4_ck
,
587 .ops
= &clkops_omap2_dflt
,
588 .enable_reg
= AM33XX_CM_WKUP_DEBUGSS_CLKCTRL
,
589 .enable_bit
= AM33XX_MODULEMODE_SWCTRL
,
590 .recalc
= &followparent_recalc
,
593 static struct clk mmu_fck
= {
595 .clkdm_name
= "gfx_l3_clkdm",
596 .parent
= &dpll_core_m4_ck
,
597 .ops
= &clkops_omap2_dflt
,
598 .enable_reg
= AM33XX_CM_GFX_MMUDATA_CLKCTRL
,
599 .enable_bit
= AM33XX_MODULEMODE_SWCTRL
,
600 .recalc
= &followparent_recalc
,
603 static struct clk cefuse_fck
= {
604 .name
= "cefuse_fck",
605 .clkdm_name
= "l4_cefuse_clkdm",
606 .parent
= &sys_clkin_ck
,
607 .enable_reg
= AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL
,
608 .enable_bit
= AM33XX_MODULEMODE_SWCTRL
,
609 .ops
= &clkops_omap2_dflt
,
610 .recalc
= &followparent_recalc
,
614 * clkdiv32 is generated from fixed division of 732.4219
616 static struct clk clkdiv32k_ick
= {
617 .name
= "clkdiv32k_ick",
618 .clkdm_name
= "clk_24mhz_clkdm",
620 .parent
= &clk_24mhz
,
621 .enable_reg
= AM33XX_CM_PER_CLKDIV32K_CLKCTRL
,
622 .enable_bit
= AM33XX_MODULEMODE_SWCTRL
,
623 .ops
= &clkops_omap2_dflt
,
626 static struct clk usbotg_fck
= {
627 .name
= "usbotg_fck",
628 .clkdm_name
= "l3s_clkdm",
629 .parent
= &dpll_per_ck
,
630 .enable_reg
= AM33XX_CM_CLKDCOLDO_DPLL_PER
,
631 .enable_bit
= AM33XX_ST_DPLL_CLKDCOLDO_SHIFT
,
632 .ops
= &clkops_omap2_dflt
,
633 .recalc
= &followparent_recalc
,
636 static struct clk ieee5000_fck
= {
637 .name
= "ieee5000_fck",
638 .clkdm_name
= "l3s_clkdm",
639 .parent
= &dpll_core_m4_div2_ck
,
640 .enable_reg
= AM33XX_CM_PER_IEEE5000_CLKCTRL
,
641 .enable_bit
= AM33XX_MODULEMODE_SWCTRL
,
642 .ops
= &clkops_omap2_dflt
,
643 .recalc
= &followparent_recalc
,
647 static const struct clksel timer1_clkmux_sel
[] = {
648 { .parent
= &sys_clkin_ck
, .rates
= div_1_0_rates
},
649 { .parent
= &clkdiv32k_ick
, .rates
= div_1_1_rates
},
650 { .parent
= &tclkin_ck
, .rates
= div_1_2_rates
},
651 { .parent
= &clk_rc32k_ck
, .rates
= div_1_3_rates
},
652 { .parent
= &clk_32768_ck
, .rates
= div_1_4_rates
},
656 static struct clk timer1_fck
= {
657 .name
= "timer1_fck",
658 .clkdm_name
= "l4ls_clkdm",
659 .parent
= &sys_clkin_ck
,
660 .init
= &omap2_init_clksel_parent
,
661 .clksel
= timer1_clkmux_sel
,
662 .clksel_reg
= AM33XX_CLKSEL_TIMER1MS_CLK
,
663 .clksel_mask
= AM33XX_CLKSEL_0_2_MASK
,
665 .recalc
= &omap2_clksel_recalc
,
668 static const struct clksel timer2_to_7_clk_sel
[] = {
669 { .parent
= &tclkin_ck
, .rates
= div_1_0_rates
},
670 { .parent
= &sys_clkin_ck
, .rates
= div_1_1_rates
},
671 { .parent
= &clkdiv32k_ick
, .rates
= div_1_2_rates
},
675 static struct clk timer2_fck
= {
676 .name
= "timer2_fck",
677 .clkdm_name
= "l4ls_clkdm",
678 .parent
= &sys_clkin_ck
,
679 .init
= &omap2_init_clksel_parent
,
680 .clksel
= timer2_to_7_clk_sel
,
681 .clksel_reg
= AM33XX_CLKSEL_TIMER2_CLK
,
682 .clksel_mask
= AM33XX_CLKSEL_0_1_MASK
,
684 .recalc
= &omap2_clksel_recalc
,
687 static struct clk timer3_fck
= {
688 .name
= "timer3_fck",
689 .clkdm_name
= "l4ls_clkdm",
690 .parent
= &sys_clkin_ck
,
691 .init
= &am33xx_init_timer_parent
,
692 .clksel
= timer2_to_7_clk_sel
,
693 .clksel_reg
= AM33XX_CLKSEL_TIMER3_CLK
,
694 .clksel_mask
= AM33XX_CLKSEL_0_1_MASK
,
696 .recalc
= &omap2_clksel_recalc
,
699 static struct clk timer4_fck
= {
700 .name
= "timer4_fck",
701 .clkdm_name
= "l4ls_clkdm",
702 .parent
= &sys_clkin_ck
,
703 .init
= &omap2_init_clksel_parent
,
704 .clksel
= timer2_to_7_clk_sel
,
705 .clksel_reg
= AM33XX_CLKSEL_TIMER4_CLK
,
706 .clksel_mask
= AM33XX_CLKSEL_0_1_MASK
,
708 .recalc
= &omap2_clksel_recalc
,
711 static struct clk timer5_fck
= {
712 .name
= "timer5_fck",
713 .clkdm_name
= "l4ls_clkdm",
714 .parent
= &sys_clkin_ck
,
715 .init
= &omap2_init_clksel_parent
,
716 .clksel
= timer2_to_7_clk_sel
,
717 .clksel_reg
= AM33XX_CLKSEL_TIMER5_CLK
,
718 .clksel_mask
= AM33XX_CLKSEL_0_1_MASK
,
720 .recalc
= &omap2_clksel_recalc
,
723 static struct clk timer6_fck
= {
724 .name
= "timer6_fck",
725 .clkdm_name
= "l4ls_clkdm",
726 .parent
= &sys_clkin_ck
,
727 .init
= &am33xx_init_timer_parent
,
728 .clksel
= timer2_to_7_clk_sel
,
729 .clksel_reg
= AM33XX_CLKSEL_TIMER6_CLK
,
730 .clksel_mask
= AM33XX_CLKSEL_0_1_MASK
,
732 .recalc
= &omap2_clksel_recalc
,
735 static struct clk timer7_fck
= {
736 .name
= "timer7_fck",
737 .clkdm_name
= "l4ls_clkdm",
738 .parent
= &sys_clkin_ck
,
739 .init
= &omap2_init_clksel_parent
,
740 .clksel
= timer2_to_7_clk_sel
,
741 .clksel_reg
= AM33XX_CLKSEL_TIMER7_CLK
,
742 .clksel_mask
= AM33XX_CLKSEL_0_1_MASK
,
744 .recalc
= &omap2_clksel_recalc
,
747 static struct clk cpsw_125mhz_gclk
= {
748 .name
= "cpsw_125mhz_gclk",
749 .clkdm_name
= "cpsw_125mhz_clkdm",
750 .parent
= &dpll_core_m5_ck
,
753 .recalc
= &omap_fixed_divisor_recalc
,
756 static const struct clksel cpsw_cpts_rft_clkmux_sel
[] = {
757 { .parent
= &dpll_core_m5_ck
, .rates
= div_1_0_rates
},
758 { .parent
= &dpll_core_m4_ck
, .rates
= div_1_1_rates
},
762 static struct clk cpsw_cpts_rft_clk
= {
763 .name
= "cpsw_cpts_rft_clk",
764 .clkdm_name
= "cpsw_125mhz_clkdm",
765 .parent
= &dpll_core_m5_ck
,
766 .clksel
= cpsw_cpts_rft_clkmux_sel
,
767 .clksel_reg
= AM33XX_CM_CPTS_RFT_CLKSEL
,
768 .clksel_mask
= AM33XX_CLKSEL_0_0_MASK
,
770 .recalc
= &followparent_recalc
,
774 static const struct clksel gpio0_dbclk_mux_sel
[] = {
775 { .parent
= &clk_rc32k_ck
, .rates
= div_1_0_rates
},
776 { .parent
= &clk_32768_ck
, .rates
= div_1_1_rates
},
777 { .parent
= &clkdiv32k_ick
, .rates
= div_1_2_rates
},
781 static struct clk gpio0_dbclk_mux_ck
= {
782 .name
= "gpio0_dbclk_mux_ck",
783 .clkdm_name
= "l4_wkup_clkdm",
784 .parent
= &clk_rc32k_ck
,
785 .init
= &omap2_init_clksel_parent
,
786 .clksel
= gpio0_dbclk_mux_sel
,
787 .clksel_reg
= AM33XX_CLKSEL_GPIO0_DBCLK
,
788 .clksel_mask
= AM33XX_CLKSEL_0_1_MASK
,
790 .recalc
= &omap2_clksel_recalc
,
793 static struct clk gpio0_dbclk
= {
794 .name
= "gpio0_dbclk",
795 .clkdm_name
= "l4_wkup_clkdm",
796 .parent
= &gpio0_dbclk_mux_ck
,
797 .enable_reg
= AM33XX_CM_WKUP_GPIO0_CLKCTRL
,
798 .enable_bit
= AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT
,
799 .ops
= &clkops_omap2_dflt
,
800 .recalc
= &followparent_recalc
,
803 static struct clk gpio1_dbclk
= {
804 .name
= "gpio1_dbclk",
805 .clkdm_name
= "l4ls_clkdm",
806 .parent
= &clkdiv32k_ick
,
807 .enable_reg
= AM33XX_CM_PER_GPIO1_CLKCTRL
,
808 .enable_bit
= AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT
,
809 .ops
= &clkops_omap2_dflt
,
810 .recalc
= &followparent_recalc
,
813 static struct clk gpio2_dbclk
= {
814 .name
= "gpio2_dbclk",
815 .clkdm_name
= "l4ls_clkdm",
816 .parent
= &clkdiv32k_ick
,
817 .enable_reg
= AM33XX_CM_PER_GPIO2_CLKCTRL
,
818 .enable_bit
= AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT
,
819 .ops
= &clkops_omap2_dflt
,
820 .recalc
= &followparent_recalc
,
823 static struct clk gpio3_dbclk
= {
824 .name
= "gpio3_dbclk",
825 .clkdm_name
= "l4ls_clkdm",
826 .parent
= &clkdiv32k_ick
,
827 .enable_reg
= AM33XX_CM_PER_GPIO3_CLKCTRL
,
828 .enable_bit
= AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT
,
829 .ops
= &clkops_omap2_dflt
,
830 .recalc
= &followparent_recalc
,
833 static const struct clksel pruss_ocp_clk_mux_sel
[] = {
834 { .parent
= &l3_gclk
, .rates
= div_1_0_rates
},
835 { .parent
= &dpll_disp_m2_ck
, .rates
= div_1_1_rates
},
839 static struct clk pruss_ocp_gclk
= {
840 .name
= "pruss_ocp_gclk",
841 .clkdm_name
= "pruss_ocp_clkdm",
843 .init
= &omap2_init_clksel_parent
,
844 .clksel
= pruss_ocp_clk_mux_sel
,
845 .clksel_reg
= AM33XX_CLKSEL_PRUSS_OCP_CLK
,
846 .clksel_mask
= AM33XX_CLKSEL_0_0_MASK
,
848 .recalc
= &followparent_recalc
,
851 static const struct clksel lcd_clk_mux_sel
[] = {
852 { .parent
= &dpll_disp_m2_ck
, .rates
= div_1_0_rates
},
853 { .parent
= &dpll_core_m5_ck
, .rates
= div_1_1_rates
},
854 { .parent
= &dpll_per_m2_ck
, .rates
= div_1_2_rates
},
858 static struct clk lcd_gclk
= {
860 .clkdm_name
= "lcdc_clkdm",
861 .parent
= &dpll_disp_m2_ck
,
862 .init
= &omap2_init_clksel_parent
,
863 .clksel
= lcd_clk_mux_sel
,
864 .clksel_reg
= AM33XX_CLKSEL_LCDC_PIXEL_CLK
,
865 .clksel_mask
= AM33XX_CLKSEL_0_1_MASK
,
867 .recalc
= &followparent_recalc
,
870 static struct clk mmc_clk
= {
872 .clkdm_name
= "l4ls_clkdm",
873 .parent
= &dpll_per_m2_ck
,
876 .recalc
= &omap_fixed_divisor_recalc
,
879 static struct clk mmc2_fck
= {
881 .clkdm_name
= "l3s_clkdm",
884 .recalc
= &followparent_recalc
,
887 static const struct clksel gfx_clksel_sel
[] = {
888 { .parent
= &dpll_core_m4_ck
, .rates
= div_1_0_rates
},
889 { .parent
= &dpll_per_m2_ck
, .rates
= div_1_1_rates
},
893 static struct clk gfx_fclk_clksel_ck
= {
894 .name
= "gfx_fclk_clksel_ck",
895 .parent
= &dpll_core_m4_ck
,
896 .clksel
= gfx_clksel_sel
,
898 .clksel_reg
= AM33XX_CLKSEL_GFX_FCLK
,
899 .clksel_mask
= AM33XX_CLKSEL_GFX_FCLK_MASK
,
900 .recalc
= &omap2_clksel_recalc
,
903 static const struct clksel_rate div_1_0_2_1_rates
[] = {
904 { .div
= 1, .val
= 0, .flags
= RATE_IN_AM33XX
},
905 { .div
= 2, .val
= 1, .flags
= RATE_IN_AM33XX
},
909 static const struct clksel gfx_div_sel
[] = {
910 { .parent
= &gfx_fclk_clksel_ck
, .rates
= div_1_0_2_1_rates
},
914 static struct clk gfx_fck_div_ck
= {
915 .name
= "gfx_fck_div_ck",
916 .clkdm_name
= "gfx_l3_clkdm",
917 .parent
= &gfx_fclk_clksel_ck
,
918 .init
= &omap2_init_clksel_parent
,
919 .clksel
= gfx_div_sel
,
920 .clksel_reg
= AM33XX_CLKSEL_GFX_FCLK
,
921 .clksel_mask
= AM33XX_CLKSEL_0_0_MASK
,
922 .recalc
= &omap2_clksel_recalc
,
923 .round_rate
= &omap2_clksel_round_rate
,
924 .set_rate
= &omap2_clksel_set_rate
,
928 static const struct clksel sysclkout_pre_sel
[] = {
929 { .parent
= &clk_32768_ck
, .rates
= div_1_0_rates
},
930 { .parent
= &l3_gclk
, .rates
= div_1_1_rates
},
931 { .parent
= &dpll_ddr_m2_ck
, .rates
= div_1_2_rates
},
932 { .parent
= &dpll_per_m2_ck
, .rates
= div_1_3_rates
},
933 { .parent
= &lcd_gclk
, .rates
= div_1_4_rates
},
937 static struct clk sysclkout_pre_ck
= {
938 .name
= "sysclkout_pre_ck",
939 .parent
= &clk_32768_ck
,
940 .init
= &omap2_init_clksel_parent
,
941 .clksel
= sysclkout_pre_sel
,
942 .clksel_reg
= AM33XX_CM_CLKOUT_CTRL
,
943 .clksel_mask
= AM33XX_CLKOUT2SOURCE_MASK
,
945 .recalc
= &omap2_clksel_recalc
,
948 /* Divide by 8 clock rates with default clock is 1/1*/
949 static const struct clksel_rate div8_rates
[] = {
950 { .div
= 1, .val
= 0, .flags
= RATE_IN_AM33XX
},
951 { .div
= 2, .val
= 1, .flags
= RATE_IN_AM33XX
},
952 { .div
= 3, .val
= 2, .flags
= RATE_IN_AM33XX
},
953 { .div
= 4, .val
= 3, .flags
= RATE_IN_AM33XX
},
954 { .div
= 5, .val
= 4, .flags
= RATE_IN_AM33XX
},
955 { .div
= 6, .val
= 5, .flags
= RATE_IN_AM33XX
},
956 { .div
= 7, .val
= 6, .flags
= RATE_IN_AM33XX
},
957 { .div
= 8, .val
= 7, .flags
= RATE_IN_AM33XX
},
961 static const struct clksel clkout2_div
[] = {
962 { .parent
= &sysclkout_pre_ck
, .rates
= div8_rates
},
966 static struct clk clkout2_ck
= {
967 .name
= "clkout2_ck",
968 .parent
= &sysclkout_pre_ck
,
969 .ops
= &clkops_omap2_dflt
,
970 .clksel
= clkout2_div
,
971 .clksel_reg
= AM33XX_CM_CLKOUT_CTRL
,
972 .clksel_mask
= AM33XX_CLKOUT2DIV_MASK
,
973 .enable_reg
= AM33XX_CM_CLKOUT_CTRL
,
974 .enable_bit
= AM33XX_CLKOUT2EN_SHIFT
,
975 .recalc
= &omap2_clksel_recalc
,
976 .round_rate
= &omap2_clksel_round_rate
,
977 .set_rate
= &omap2_clksel_set_rate
,
980 static const struct clksel wdt_clkmux_sel
[] = {
981 { .parent
= &clk_rc32k_ck
, .rates
= div_1_0_rates
},
982 { .parent
= &clkdiv32k_ick
, .rates
= div_1_1_rates
},
986 static struct clk wdt1_fck
= {
988 .clkdm_name
= "l4_wkup_clkdm",
989 .parent
= &clk_rc32k_ck
,
990 .init
= &omap2_init_clksel_parent
,
991 .clksel
= wdt_clkmux_sel
,
992 .clksel_reg
= AM33XX_CLKSEL_WDT1_CLK
,
993 .clksel_mask
= AM33XX_CLKSEL_0_1_MASK
,
995 .recalc
= &omap2_clksel_recalc
,
1001 static struct omap_clk am33xx_clks
[] = {
1002 CLK(NULL
, "clk_32768_ck", &clk_32768_ck
, CK_AM33XX
),
1003 CLK(NULL
, "clk_rc32k_ck", &clk_rc32k_ck
, CK_AM33XX
),
1004 CLK(NULL
, "virt_19200000_ck", &virt_19200000_ck
, CK_AM33XX
),
1005 CLK(NULL
, "virt_24000000_ck", &virt_24000000_ck
, CK_AM33XX
),
1006 CLK(NULL
, "virt_25000000_ck", &virt_25000000_ck
, CK_AM33XX
),
1007 CLK(NULL
, "virt_26000000_ck", &virt_26000000_ck
, CK_AM33XX
),
1008 CLK(NULL
, "sys_clkin_ck", &sys_clkin_ck
, CK_AM33XX
),
1009 CLK(NULL
, "tclkin_ck", &tclkin_ck
, CK_AM33XX
),
1010 CLK(NULL
, "dpll_core_ck", &dpll_core_ck
, CK_AM33XX
),
1011 CLK(NULL
, "dpll_core_x2_ck", &dpll_core_x2_ck
, CK_AM33XX
),
1012 CLK(NULL
, "dpll_core_m4_ck", &dpll_core_m4_ck
, CK_AM33XX
),
1013 CLK(NULL
, "dpll_core_m5_ck", &dpll_core_m5_ck
, CK_AM33XX
),
1014 CLK(NULL
, "dpll_core_m6_ck", &dpll_core_m6_ck
, CK_AM33XX
),
1015 CLK(NULL
, "dpll_mpu_ck", &dpll_mpu_ck
, CK_AM33XX
),
1016 CLK(NULL
, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck
, CK_AM33XX
),
1017 CLK(NULL
, "dpll_ddr_ck", &dpll_ddr_ck
, CK_AM33XX
),
1018 CLK(NULL
, "dpll_ddr_m2_ck", &dpll_ddr_m2_ck
, CK_AM33XX
),
1019 CLK(NULL
, "dpll_ddr_m2_div2_ck", &dpll_ddr_m2_div2_ck
, CK_AM33XX
),
1020 CLK(NULL
, "dpll_disp_ck", &dpll_disp_ck
, CK_AM33XX
),
1021 CLK(NULL
, "dpll_disp_m2_ck", &dpll_disp_m2_ck
, CK_AM33XX
),
1022 CLK(NULL
, "dpll_per_ck", &dpll_per_ck
, CK_AM33XX
),
1023 CLK(NULL
, "dpll_per_m2_ck", &dpll_per_m2_ck
, CK_AM33XX
),
1024 CLK(NULL
, "dpll_per_m2_div4_wkupdm_ck", &dpll_per_m2_div4_wkupdm_ck
, CK_AM33XX
),
1025 CLK(NULL
, "dpll_per_m2_div4_ck", &dpll_per_m2_div4_ck
, CK_AM33XX
),
1026 CLK(NULL
, "adc_tsc_fck", &adc_tsc_fck
, CK_AM33XX
),
1027 CLK(NULL
, "cefuse_fck", &cefuse_fck
, CK_AM33XX
),
1028 CLK(NULL
, "clkdiv32k_ick", &clkdiv32k_ick
, CK_AM33XX
),
1029 CLK(NULL
, "dcan0_fck", &dcan0_fck
, CK_AM33XX
),
1030 CLK(NULL
, "dcan1_fck", &dcan1_fck
, CK_AM33XX
),
1031 CLK(NULL
, "debugss_ick", &debugss_ick
, CK_AM33XX
),
1032 CLK(NULL
, "pruss_ocp_gclk", &pruss_ocp_gclk
, CK_AM33XX
),
1033 CLK("davinci-mcasp.0", NULL
, &mcasp0_fck
, CK_AM33XX
),
1034 CLK("davinci-mcasp.1", NULL
, &mcasp1_fck
, CK_AM33XX
),
1035 CLK("NULL", "mmc2_fck", &mmc2_fck
, CK_AM33XX
),
1036 CLK(NULL
, "mmu_fck", &mmu_fck
, CK_AM33XX
),
1037 CLK(NULL
, "smartreflex0_fck", &smartreflex0_fck
, CK_AM33XX
),
1038 CLK(NULL
, "smartreflex1_fck", &smartreflex1_fck
, CK_AM33XX
),
1039 CLK(NULL
, "timer1_fck", &timer1_fck
, CK_AM33XX
),
1040 CLK(NULL
, "timer2_fck", &timer2_fck
, CK_AM33XX
),
1041 CLK(NULL
, "timer3_fck", &timer3_fck
, CK_AM33XX
),
1042 CLK(NULL
, "timer4_fck", &timer4_fck
, CK_AM33XX
),
1043 CLK(NULL
, "timer5_fck", &timer5_fck
, CK_AM33XX
),
1044 CLK(NULL
, "timer6_fck", &timer6_fck
, CK_AM33XX
),
1045 CLK(NULL
, "timer7_fck", &timer7_fck
, CK_AM33XX
),
1046 CLK(NULL
, "usbotg_fck", &usbotg_fck
, CK_AM33XX
),
1047 CLK(NULL
, "ieee5000_fck", &ieee5000_fck
, CK_AM33XX
),
1048 CLK(NULL
, "wdt1_fck", &wdt1_fck
, CK_AM33XX
),
1049 CLK(NULL
, "l4_rtc_gclk", &l4_rtc_gclk
, CK_AM33XX
),
1050 CLK(NULL
, "l3_gclk", &l3_gclk
, CK_AM33XX
),
1051 CLK(NULL
, "dpll_core_m4_div2_ck", &dpll_core_m4_div2_ck
, CK_AM33XX
),
1052 CLK(NULL
, "l4hs_gclk", &l4hs_gclk
, CK_AM33XX
),
1053 CLK(NULL
, "l3s_gclk", &l3s_gclk
, CK_AM33XX
),
1054 CLK(NULL
, "l4fw_gclk", &l4fw_gclk
, CK_AM33XX
),
1055 CLK(NULL
, "l4ls_gclk", &l4ls_gclk
, CK_AM33XX
),
1056 CLK(NULL
, "clk_24mhz", &clk_24mhz
, CK_AM33XX
),
1057 CLK(NULL
, "sysclk_div_ck", &sysclk_div_ck
, CK_AM33XX
),
1058 CLK(NULL
, "cpsw_125mhz_gclk", &cpsw_125mhz_gclk
, CK_AM33XX
),
1059 CLK(NULL
, "cpsw_cpts_rft_clk", &cpsw_cpts_rft_clk
, CK_AM33XX
),
1060 CLK(NULL
, "gpio0_dbclk_mux_ck", &gpio0_dbclk_mux_ck
, CK_AM33XX
),
1061 CLK(NULL
, "gpio0_dbclk", &gpio0_dbclk
, CK_AM33XX
),
1062 CLK(NULL
, "gpio1_dbclk", &gpio1_dbclk
, CK_AM33XX
),
1063 CLK(NULL
, "gpio2_dbclk", &gpio2_dbclk
, CK_AM33XX
),
1064 CLK(NULL
, "gpio3_dbclk", &gpio3_dbclk
, CK_AM33XX
),
1065 CLK(NULL
, "lcd_gclk", &lcd_gclk
, CK_AM33XX
),
1066 CLK(NULL
, "mmc_clk", &mmc_clk
, CK_AM33XX
),
1067 CLK(NULL
, "gfx_fclk_clksel_ck", &gfx_fclk_clksel_ck
, CK_AM33XX
),
1068 CLK(NULL
, "gfx_fck_div_ck", &gfx_fck_div_ck
, CK_AM33XX
),
1069 CLK(NULL
, "sysclkout_pre_ck", &sysclkout_pre_ck
, CK_AM33XX
),
1070 CLK(NULL
, "clkout2_ck", &clkout2_ck
, CK_AM33XX
),
1073 int __init
am33xx_clk_init(void)
1078 if (soc_is_am33xx()) {
1079 cpu_mask
= RATE_IN_AM33XX
;
1080 cpu_clkflg
= CK_AM33XX
;
1083 clk_init(&omap2_clk_functions
);
1085 for (c
= am33xx_clks
; c
< am33xx_clks
+ ARRAY_SIZE(am33xx_clks
); c
++)
1086 clk_preinit(c
->lk
.clk
);
1088 for (c
= am33xx_clks
; c
< am33xx_clks
+ ARRAY_SIZE(am33xx_clks
); c
++) {
1089 if (c
->cpu
& cpu_clkflg
) {
1091 clk_register(c
->lk
.clk
);
1092 omap2_init_clk_clkdm(c
->lk
.clk
);
1096 recalculate_root_clocks();
1099 * Only enable those clocks we will need, let the drivers
1100 * enable other clocks as necessary
1102 clk_enable_init_clocks();