2 * OMAP3xxx clockdomains
4 * Copyright (C) 2008-2011 Texas Instruments, Inc.
5 * Copyright (C) 2008-2010 Nokia Corporation
7 * Paul Walmsley, Jouni Högander
9 * This file contains clockdomains and clockdomain wakeup/sleep
10 * dependencies for the OMAP3xxx chips. Some notes:
12 * A useful validation rule for struct clockdomain: Any clockdomain
13 * referenced by a wkdep_srcs or sleepdep_srcs array must have a
14 * dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really just
15 * software-controllable dependencies. Non-software-controllable
16 * dependencies do exist, but they are not encoded below (yet).
18 * The overly-specific dep_bit names are due to a bit name collision
19 * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
20 * value are the same for all powerdomains: 2
22 * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
24 * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
29 * -> Port the Sleep/Wakeup dependencies for the domains
30 * from the Power domain framework
33 #include <linux/kernel.h>
37 #include "clockdomain.h"
38 #include "prm2xxx_3xxx.h"
39 #include "cm2xxx_3xxx.h"
40 #include "cm-regbits-34xx.h"
41 #include "prm-regbits-34xx.h"
44 * Clockdomain dependencies for wkdeps/sleepdeps
46 * XXX Hardware dependencies (e.g., dependencies that cannot be
47 * changed in software) are not included here yet, but should be.
50 /* OMAP3-specific possible dependencies */
53 * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
54 * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
56 static struct clkdm_dep gfx_sgx_3xxx_wkdeps
[] = {
57 { .clkdm_name
= "iva2_clkdm" },
58 { .clkdm_name
= "mpu_clkdm" },
59 { .clkdm_name
= "wkup_clkdm" },
63 static struct clkdm_dep gfx_sgx_am35x_wkdeps
[] = {
64 { .clkdm_name
= "mpu_clkdm" },
65 { .clkdm_name
= "wkup_clkdm" },
69 /* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
70 static struct clkdm_dep per_wkdeps
[] = {
71 { .clkdm_name
= "core_l3_clkdm" },
72 { .clkdm_name
= "core_l4_clkdm" },
73 { .clkdm_name
= "iva2_clkdm" },
74 { .clkdm_name
= "mpu_clkdm" },
75 { .clkdm_name
= "wkup_clkdm" },
79 static struct clkdm_dep per_am35x_wkdeps
[] = {
80 { .clkdm_name
= "core_l3_clkdm" },
81 { .clkdm_name
= "core_l4_clkdm" },
82 { .clkdm_name
= "mpu_clkdm" },
83 { .clkdm_name
= "wkup_clkdm" },
87 /* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
88 static struct clkdm_dep usbhost_wkdeps
[] = {
89 { .clkdm_name
= "core_l3_clkdm" },
90 { .clkdm_name
= "core_l4_clkdm" },
91 { .clkdm_name
= "iva2_clkdm" },
92 { .clkdm_name
= "mpu_clkdm" },
93 { .clkdm_name
= "wkup_clkdm" },
97 static struct clkdm_dep usbhost_am35x_wkdeps
[] = {
98 { .clkdm_name
= "core_l3_clkdm" },
99 { .clkdm_name
= "core_l4_clkdm" },
100 { .clkdm_name
= "mpu_clkdm" },
101 { .clkdm_name
= "wkup_clkdm" },
105 /* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
106 static struct clkdm_dep mpu_3xxx_wkdeps
[] = {
107 { .clkdm_name
= "core_l3_clkdm" },
108 { .clkdm_name
= "core_l4_clkdm" },
109 { .clkdm_name
= "iva2_clkdm" },
110 { .clkdm_name
= "dss_clkdm" },
111 { .clkdm_name
= "per_clkdm" },
115 static struct clkdm_dep mpu_am35x_wkdeps
[] = {
116 { .clkdm_name
= "core_l3_clkdm" },
117 { .clkdm_name
= "core_l4_clkdm" },
118 { .clkdm_name
= "dss_clkdm" },
119 { .clkdm_name
= "per_clkdm" },
123 /* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
124 static struct clkdm_dep iva2_wkdeps
[] = {
125 { .clkdm_name
= "core_l3_clkdm" },
126 { .clkdm_name
= "core_l4_clkdm" },
127 { .clkdm_name
= "mpu_clkdm" },
128 { .clkdm_name
= "wkup_clkdm" },
129 { .clkdm_name
= "dss_clkdm" },
130 { .clkdm_name
= "per_clkdm" },
134 /* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
135 static struct clkdm_dep cam_wkdeps
[] = {
136 { .clkdm_name
= "iva2_clkdm" },
137 { .clkdm_name
= "mpu_clkdm" },
138 { .clkdm_name
= "wkup_clkdm" },
142 /* 3430 PM_WKDEP_DSS: IVA2, MPU, WKUP */
143 static struct clkdm_dep dss_wkdeps
[] = {
144 { .clkdm_name
= "iva2_clkdm" },
145 { .clkdm_name
= "mpu_clkdm" },
146 { .clkdm_name
= "wkup_clkdm" },
150 static struct clkdm_dep dss_am35x_wkdeps
[] = {
151 { .clkdm_name
= "mpu_clkdm" },
152 { .clkdm_name
= "wkup_clkdm" },
156 /* 3430: PM_WKDEP_NEON: MPU */
157 static struct clkdm_dep neon_wkdeps
[] = {
158 { .clkdm_name
= "mpu_clkdm" },
162 /* Sleep dependency source arrays for OMAP3-specific clkdms */
164 /* 3430: CM_SLEEPDEP_DSS: MPU, IVA */
165 static struct clkdm_dep dss_sleepdeps
[] = {
166 { .clkdm_name
= "mpu_clkdm" },
167 { .clkdm_name
= "iva2_clkdm" },
171 static struct clkdm_dep dss_am35x_sleepdeps
[] = {
172 { .clkdm_name
= "mpu_clkdm" },
176 /* 3430: CM_SLEEPDEP_PER: MPU, IVA */
177 static struct clkdm_dep per_sleepdeps
[] = {
178 { .clkdm_name
= "mpu_clkdm" },
179 { .clkdm_name
= "iva2_clkdm" },
183 static struct clkdm_dep per_am35x_sleepdeps
[] = {
184 { .clkdm_name
= "mpu_clkdm" },
188 /* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
189 static struct clkdm_dep usbhost_sleepdeps
[] = {
190 { .clkdm_name
= "mpu_clkdm" },
191 { .clkdm_name
= "iva2_clkdm" },
195 static struct clkdm_dep usbhost_am35x_sleepdeps
[] = {
196 { .clkdm_name
= "mpu_clkdm" },
200 /* 3430: CM_SLEEPDEP_CAM: MPU */
201 static struct clkdm_dep cam_sleepdeps
[] = {
202 { .clkdm_name
= "mpu_clkdm" },
207 * 3430ES1: CM_SLEEPDEP_GFX: MPU
208 * 3430ES2: CM_SLEEPDEP_SGX: MPU
209 * These can share data since they will never be present simultaneously
210 * on the same device.
212 static struct clkdm_dep gfx_sgx_sleepdeps
[] = {
213 { .clkdm_name
= "mpu_clkdm" },
221 static struct clockdomain mpu_3xxx_clkdm
= {
223 .pwrdm
= { .name
= "mpu_pwrdm" },
224 .flags
= CLKDM_CAN_HWSUP
| CLKDM_CAN_FORCE_WAKEUP
,
225 .dep_bit
= OMAP3430_EN_MPU_SHIFT
,
226 .wkdep_srcs
= mpu_3xxx_wkdeps
,
227 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_MPU_MASK
,
230 static struct clockdomain mpu_am35x_clkdm
= {
232 .pwrdm
= { .name
= "mpu_pwrdm" },
233 .flags
= CLKDM_CAN_HWSUP
| CLKDM_CAN_FORCE_WAKEUP
,
234 .dep_bit
= OMAP3430_EN_MPU_SHIFT
,
235 .wkdep_srcs
= mpu_am35x_wkdeps
,
236 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_MPU_MASK
,
239 static struct clockdomain neon_clkdm
= {
240 .name
= "neon_clkdm",
241 .pwrdm
= { .name
= "neon_pwrdm" },
242 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
243 .wkdep_srcs
= neon_wkdeps
,
244 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_NEON_MASK
,
247 static struct clockdomain iva2_clkdm
= {
248 .name
= "iva2_clkdm",
249 .pwrdm
= { .name
= "iva2_pwrdm" },
250 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
251 .dep_bit
= OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT
,
252 .wkdep_srcs
= iva2_wkdeps
,
253 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_IVA2_MASK
,
256 static struct clockdomain gfx_3430es1_clkdm
= {
258 .pwrdm
= { .name
= "gfx_pwrdm" },
259 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
260 .wkdep_srcs
= gfx_sgx_3xxx_wkdeps
,
261 .sleepdep_srcs
= gfx_sgx_sleepdeps
,
262 .clktrctrl_mask
= OMAP3430ES1_CLKTRCTRL_GFX_MASK
,
265 static struct clockdomain sgx_clkdm
= {
267 .pwrdm
= { .name
= "sgx_pwrdm" },
268 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
269 .wkdep_srcs
= gfx_sgx_3xxx_wkdeps
,
270 .sleepdep_srcs
= gfx_sgx_sleepdeps
,
271 .clktrctrl_mask
= OMAP3430ES2_CLKTRCTRL_SGX_MASK
,
274 static struct clockdomain sgx_am35x_clkdm
= {
276 .pwrdm
= { .name
= "sgx_pwrdm" },
277 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
278 .wkdep_srcs
= gfx_sgx_am35x_wkdeps
,
279 .sleepdep_srcs
= gfx_sgx_sleepdeps
,
280 .clktrctrl_mask
= OMAP3430ES2_CLKTRCTRL_SGX_MASK
,
284 * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
285 * then that information was removed from the 34xx ES2+ TRM. It is
286 * unclear whether the core is still there, but the clockdomain logic
287 * is there, and must be programmed to an appropriate state if the
288 * CORE clockdomain is to become inactive.
290 static struct clockdomain d2d_clkdm
= {
292 .pwrdm
= { .name
= "core_pwrdm" },
293 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
294 .clktrctrl_mask
= OMAP3430ES1_CLKTRCTRL_D2D_MASK
,
298 * XXX add usecounting for clkdm dependencies, otherwise the presence
299 * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
300 * could cause trouble
302 static struct clockdomain core_l3_3xxx_clkdm
= {
303 .name
= "core_l3_clkdm",
304 .pwrdm
= { .name
= "core_pwrdm" },
305 .flags
= CLKDM_CAN_HWSUP
,
306 .dep_bit
= OMAP3430_EN_CORE_SHIFT
,
307 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_L3_MASK
,
311 * XXX add usecounting for clkdm dependencies, otherwise the presence
312 * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
313 * could cause trouble
315 static struct clockdomain core_l4_3xxx_clkdm
= {
316 .name
= "core_l4_clkdm",
317 .pwrdm
= { .name
= "core_pwrdm" },
318 .flags
= CLKDM_CAN_HWSUP
,
319 .dep_bit
= OMAP3430_EN_CORE_SHIFT
,
320 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_L4_MASK
,
323 /* Another case of bit name collisions between several registers: EN_DSS */
324 static struct clockdomain dss_3xxx_clkdm
= {
326 .pwrdm
= { .name
= "dss_pwrdm" },
327 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
328 .dep_bit
= OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT
,
329 .wkdep_srcs
= dss_wkdeps
,
330 .sleepdep_srcs
= dss_sleepdeps
,
331 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_DSS_MASK
,
334 static struct clockdomain dss_am35x_clkdm
= {
336 .pwrdm
= { .name
= "dss_pwrdm" },
337 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
338 .dep_bit
= OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT
,
339 .wkdep_srcs
= dss_am35x_wkdeps
,
340 .sleepdep_srcs
= dss_am35x_sleepdeps
,
341 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_DSS_MASK
,
344 static struct clockdomain cam_clkdm
= {
346 .pwrdm
= { .name
= "cam_pwrdm" },
347 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
348 .wkdep_srcs
= cam_wkdeps
,
349 .sleepdep_srcs
= cam_sleepdeps
,
350 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_CAM_MASK
,
353 static struct clockdomain usbhost_clkdm
= {
354 .name
= "usbhost_clkdm",
355 .pwrdm
= { .name
= "usbhost_pwrdm" },
356 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
357 .wkdep_srcs
= usbhost_wkdeps
,
358 .sleepdep_srcs
= usbhost_sleepdeps
,
359 .clktrctrl_mask
= OMAP3430ES2_CLKTRCTRL_USBHOST_MASK
,
362 static struct clockdomain usbhost_am35x_clkdm
= {
363 .name
= "usbhost_clkdm",
364 .pwrdm
= { .name
= "core_pwrdm" },
365 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
366 .wkdep_srcs
= usbhost_am35x_wkdeps
,
367 .sleepdep_srcs
= usbhost_am35x_sleepdeps
,
368 .clktrctrl_mask
= OMAP3430ES2_CLKTRCTRL_USBHOST_MASK
,
371 static struct clockdomain per_clkdm
= {
373 .pwrdm
= { .name
= "per_pwrdm" },
374 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
375 .dep_bit
= OMAP3430_EN_PER_SHIFT
,
376 .wkdep_srcs
= per_wkdeps
,
377 .sleepdep_srcs
= per_sleepdeps
,
378 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_PER_MASK
,
381 static struct clockdomain per_am35x_clkdm
= {
383 .pwrdm
= { .name
= "per_pwrdm" },
384 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
385 .dep_bit
= OMAP3430_EN_PER_SHIFT
,
386 .wkdep_srcs
= per_am35x_wkdeps
,
387 .sleepdep_srcs
= per_am35x_sleepdeps
,
388 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_PER_MASK
,
391 static struct clockdomain emu_clkdm
= {
393 .pwrdm
= { .name
= "emu_pwrdm" },
394 .flags
= (CLKDM_CAN_ENABLE_AUTO
| CLKDM_CAN_SWSUP
|
395 CLKDM_MISSING_IDLE_REPORTING
),
396 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_EMU_MASK
,
399 static struct clockdomain dpll1_clkdm
= {
400 .name
= "dpll1_clkdm",
401 .pwrdm
= { .name
= "dpll1_pwrdm" },
404 static struct clockdomain dpll2_clkdm
= {
405 .name
= "dpll2_clkdm",
406 .pwrdm
= { .name
= "dpll2_pwrdm" },
409 static struct clockdomain dpll3_clkdm
= {
410 .name
= "dpll3_clkdm",
411 .pwrdm
= { .name
= "dpll3_pwrdm" },
414 static struct clockdomain dpll4_clkdm
= {
415 .name
= "dpll4_clkdm",
416 .pwrdm
= { .name
= "dpll4_pwrdm" },
419 static struct clockdomain dpll5_clkdm
= {
420 .name
= "dpll5_clkdm",
421 .pwrdm
= { .name
= "dpll5_pwrdm" },
425 * Clockdomain hwsup dependencies
428 static struct clkdm_autodep clkdm_autodeps
[] = {
430 .clkdm
= { .name
= "mpu_clkdm" },
433 .clkdm
= { .name
= "iva2_clkdm" },
436 .clkdm
= { .name
= NULL
},
440 static struct clkdm_autodep clkdm_am35x_autodeps
[] = {
442 .clkdm
= { .name
= "mpu_clkdm" },
445 .clkdm
= { .name
= NULL
},
453 static struct clockdomain
*clockdomains_common
[] __initdata
= {
465 static struct clockdomain
*clockdomains_omap3430
[] __initdata
= {
476 static struct clockdomain
*clockdomains_omap3430es1
[] __initdata
= {
481 static struct clockdomain
*clockdomains_omap3430es2plus
[] __initdata
= {
488 static struct clockdomain
*clockdomains_am35x
[] __initdata
= {
493 &usbhost_am35x_clkdm
,
498 void __init
omap3xxx_clockdomains_init(void)
500 struct clockdomain
**sc
;
503 if (!cpu_is_omap34xx())
506 clkdm_register_platform_funcs(&omap3_clkdm_operations
);
507 clkdm_register_clkdms(clockdomains_common
);
511 if (rev
== AM35XX_REV_ES1_0
|| rev
== AM35XX_REV_ES1_1
) {
512 clkdm_register_clkdms(clockdomains_am35x
);
513 clkdm_register_autodeps(clkdm_am35x_autodeps
);
515 clkdm_register_clkdms(clockdomains_omap3430
);
517 sc
= (rev
== OMAP3430_REV_ES1_0
) ?
518 clockdomains_omap3430es1
: clockdomains_omap3430es2plus
;
520 clkdm_register_clkdms(sc
);
521 clkdm_register_autodeps(clkdm_autodeps
);
524 clkdm_complete_init();