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>
36 #include "clockdomain.h"
37 #include "prm2xxx_3xxx.h"
38 #include "cm2xxx_3xxx.h"
39 #include "cm-regbits-34xx.h"
40 #include "prm-regbits-34xx.h"
43 * Clockdomain dependencies for wkdeps/sleepdeps
45 * XXX Hardware dependencies (e.g., dependencies that cannot be
46 * changed in software) are not included here yet, but should be.
49 /* OMAP3-specific possible dependencies */
52 * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
53 * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
55 static struct clkdm_dep gfx_sgx_3xxx_wkdeps
[] = {
56 { .clkdm_name
= "iva2_clkdm" },
57 { .clkdm_name
= "mpu_clkdm" },
58 { .clkdm_name
= "wkup_clkdm" },
62 static struct clkdm_dep gfx_sgx_am35x_wkdeps
[] = {
63 { .clkdm_name
= "mpu_clkdm" },
64 { .clkdm_name
= "wkup_clkdm" },
68 /* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
69 static struct clkdm_dep per_wkdeps
[] = {
70 { .clkdm_name
= "core_l3_clkdm" },
71 { .clkdm_name
= "core_l4_clkdm" },
72 { .clkdm_name
= "iva2_clkdm" },
73 { .clkdm_name
= "mpu_clkdm" },
74 { .clkdm_name
= "wkup_clkdm" },
78 static struct clkdm_dep per_am35x_wkdeps
[] = {
79 { .clkdm_name
= "core_l3_clkdm" },
80 { .clkdm_name
= "core_l4_clkdm" },
81 { .clkdm_name
= "mpu_clkdm" },
82 { .clkdm_name
= "wkup_clkdm" },
86 /* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
87 static struct clkdm_dep usbhost_wkdeps
[] = {
88 { .clkdm_name
= "core_l3_clkdm" },
89 { .clkdm_name
= "core_l4_clkdm" },
90 { .clkdm_name
= "iva2_clkdm" },
91 { .clkdm_name
= "mpu_clkdm" },
92 { .clkdm_name
= "wkup_clkdm" },
96 static struct clkdm_dep usbhost_am35x_wkdeps
[] = {
97 { .clkdm_name
= "core_l3_clkdm" },
98 { .clkdm_name
= "core_l4_clkdm" },
99 { .clkdm_name
= "mpu_clkdm" },
100 { .clkdm_name
= "wkup_clkdm" },
104 /* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
105 static struct clkdm_dep mpu_3xxx_wkdeps
[] = {
106 { .clkdm_name
= "core_l3_clkdm" },
107 { .clkdm_name
= "core_l4_clkdm" },
108 { .clkdm_name
= "iva2_clkdm" },
109 { .clkdm_name
= "dss_clkdm" },
110 { .clkdm_name
= "per_clkdm" },
114 static struct clkdm_dep mpu_am35x_wkdeps
[] = {
115 { .clkdm_name
= "core_l3_clkdm" },
116 { .clkdm_name
= "core_l4_clkdm" },
117 { .clkdm_name
= "dss_clkdm" },
118 { .clkdm_name
= "per_clkdm" },
122 /* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
123 static struct clkdm_dep iva2_wkdeps
[] = {
124 { .clkdm_name
= "core_l3_clkdm" },
125 { .clkdm_name
= "core_l4_clkdm" },
126 { .clkdm_name
= "mpu_clkdm" },
127 { .clkdm_name
= "wkup_clkdm" },
128 { .clkdm_name
= "dss_clkdm" },
129 { .clkdm_name
= "per_clkdm" },
133 /* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
134 static struct clkdm_dep cam_wkdeps
[] = {
135 { .clkdm_name
= "iva2_clkdm" },
136 { .clkdm_name
= "mpu_clkdm" },
137 { .clkdm_name
= "wkup_clkdm" },
141 /* 3430 PM_WKDEP_DSS: IVA2, MPU, WKUP */
142 static struct clkdm_dep dss_wkdeps
[] = {
143 { .clkdm_name
= "iva2_clkdm" },
144 { .clkdm_name
= "mpu_clkdm" },
145 { .clkdm_name
= "wkup_clkdm" },
149 static struct clkdm_dep dss_am35x_wkdeps
[] = {
150 { .clkdm_name
= "mpu_clkdm" },
151 { .clkdm_name
= "wkup_clkdm" },
155 /* 3430: PM_WKDEP_NEON: MPU */
156 static struct clkdm_dep neon_wkdeps
[] = {
157 { .clkdm_name
= "mpu_clkdm" },
161 /* Sleep dependency source arrays for OMAP3-specific clkdms */
163 /* 3430: CM_SLEEPDEP_DSS: MPU, IVA */
164 static struct clkdm_dep dss_sleepdeps
[] = {
165 { .clkdm_name
= "mpu_clkdm" },
166 { .clkdm_name
= "iva2_clkdm" },
170 static struct clkdm_dep dss_am35x_sleepdeps
[] = {
171 { .clkdm_name
= "mpu_clkdm" },
175 /* 3430: CM_SLEEPDEP_PER: MPU, IVA */
176 static struct clkdm_dep per_sleepdeps
[] = {
177 { .clkdm_name
= "mpu_clkdm" },
178 { .clkdm_name
= "iva2_clkdm" },
182 static struct clkdm_dep per_am35x_sleepdeps
[] = {
183 { .clkdm_name
= "mpu_clkdm" },
187 /* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
188 static struct clkdm_dep usbhost_sleepdeps
[] = {
189 { .clkdm_name
= "mpu_clkdm" },
190 { .clkdm_name
= "iva2_clkdm" },
194 static struct clkdm_dep usbhost_am35x_sleepdeps
[] = {
195 { .clkdm_name
= "mpu_clkdm" },
199 /* 3430: CM_SLEEPDEP_CAM: MPU */
200 static struct clkdm_dep cam_sleepdeps
[] = {
201 { .clkdm_name
= "mpu_clkdm" },
206 * 3430ES1: CM_SLEEPDEP_GFX: MPU
207 * 3430ES2: CM_SLEEPDEP_SGX: MPU
208 * These can share data since they will never be present simultaneously
209 * on the same device.
211 static struct clkdm_dep gfx_sgx_sleepdeps
[] = {
212 { .clkdm_name
= "mpu_clkdm" },
220 static struct clockdomain mpu_3xxx_clkdm
= {
222 .pwrdm
= { .name
= "mpu_pwrdm" },
223 .flags
= CLKDM_CAN_HWSUP
| CLKDM_CAN_FORCE_WAKEUP
,
224 .dep_bit
= OMAP3430_EN_MPU_SHIFT
,
225 .wkdep_srcs
= mpu_3xxx_wkdeps
,
226 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_MPU_MASK
,
229 static struct clockdomain mpu_am35x_clkdm
= {
231 .pwrdm
= { .name
= "mpu_pwrdm" },
232 .flags
= CLKDM_CAN_HWSUP
| CLKDM_CAN_FORCE_WAKEUP
,
233 .dep_bit
= OMAP3430_EN_MPU_SHIFT
,
234 .wkdep_srcs
= mpu_am35x_wkdeps
,
235 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_MPU_MASK
,
238 static struct clockdomain neon_clkdm
= {
239 .name
= "neon_clkdm",
240 .pwrdm
= { .name
= "neon_pwrdm" },
241 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
242 .wkdep_srcs
= neon_wkdeps
,
243 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_NEON_MASK
,
246 static struct clockdomain iva2_clkdm
= {
247 .name
= "iva2_clkdm",
248 .pwrdm
= { .name
= "iva2_pwrdm" },
249 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
250 .dep_bit
= OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT
,
251 .wkdep_srcs
= iva2_wkdeps
,
252 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_IVA2_MASK
,
255 static struct clockdomain gfx_3430es1_clkdm
= {
257 .pwrdm
= { .name
= "gfx_pwrdm" },
258 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
259 .wkdep_srcs
= gfx_sgx_3xxx_wkdeps
,
260 .sleepdep_srcs
= gfx_sgx_sleepdeps
,
261 .clktrctrl_mask
= OMAP3430ES1_CLKTRCTRL_GFX_MASK
,
264 static struct clockdomain sgx_clkdm
= {
266 .pwrdm
= { .name
= "sgx_pwrdm" },
267 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
268 .wkdep_srcs
= gfx_sgx_3xxx_wkdeps
,
269 .sleepdep_srcs
= gfx_sgx_sleepdeps
,
270 .clktrctrl_mask
= OMAP3430ES2_CLKTRCTRL_SGX_MASK
,
273 static struct clockdomain sgx_am35x_clkdm
= {
275 .pwrdm
= { .name
= "sgx_pwrdm" },
276 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
277 .wkdep_srcs
= gfx_sgx_am35x_wkdeps
,
278 .sleepdep_srcs
= gfx_sgx_sleepdeps
,
279 .clktrctrl_mask
= OMAP3430ES2_CLKTRCTRL_SGX_MASK
,
283 * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
284 * then that information was removed from the 34xx ES2+ TRM. It is
285 * unclear whether the core is still there, but the clockdomain logic
286 * is there, and must be programmed to an appropriate state if the
287 * CORE clockdomain is to become inactive.
289 static struct clockdomain d2d_clkdm
= {
291 .pwrdm
= { .name
= "core_pwrdm" },
292 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
293 .clktrctrl_mask
= OMAP3430ES1_CLKTRCTRL_D2D_MASK
,
297 * XXX add usecounting for clkdm dependencies, otherwise the presence
298 * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
299 * could cause trouble
301 static struct clockdomain core_l3_3xxx_clkdm
= {
302 .name
= "core_l3_clkdm",
303 .pwrdm
= { .name
= "core_pwrdm" },
304 .flags
= CLKDM_CAN_HWSUP
,
305 .dep_bit
= OMAP3430_EN_CORE_SHIFT
,
306 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_L3_MASK
,
310 * XXX add usecounting for clkdm dependencies, otherwise the presence
311 * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
312 * could cause trouble
314 static struct clockdomain core_l4_3xxx_clkdm
= {
315 .name
= "core_l4_clkdm",
316 .pwrdm
= { .name
= "core_pwrdm" },
317 .flags
= CLKDM_CAN_HWSUP
,
318 .dep_bit
= OMAP3430_EN_CORE_SHIFT
,
319 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_L4_MASK
,
322 /* Another case of bit name collisions between several registers: EN_DSS */
323 static struct clockdomain dss_3xxx_clkdm
= {
325 .pwrdm
= { .name
= "dss_pwrdm" },
326 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
327 .dep_bit
= OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT
,
328 .wkdep_srcs
= dss_wkdeps
,
329 .sleepdep_srcs
= dss_sleepdeps
,
330 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_DSS_MASK
,
333 static struct clockdomain dss_am35x_clkdm
= {
335 .pwrdm
= { .name
= "dss_pwrdm" },
336 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
337 .dep_bit
= OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT
,
338 .wkdep_srcs
= dss_am35x_wkdeps
,
339 .sleepdep_srcs
= dss_am35x_sleepdeps
,
340 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_DSS_MASK
,
343 static struct clockdomain cam_clkdm
= {
345 .pwrdm
= { .name
= "cam_pwrdm" },
346 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
347 .wkdep_srcs
= cam_wkdeps
,
348 .sleepdep_srcs
= cam_sleepdeps
,
349 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_CAM_MASK
,
352 static struct clockdomain usbhost_clkdm
= {
353 .name
= "usbhost_clkdm",
354 .pwrdm
= { .name
= "usbhost_pwrdm" },
355 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
356 .wkdep_srcs
= usbhost_wkdeps
,
357 .sleepdep_srcs
= usbhost_sleepdeps
,
358 .clktrctrl_mask
= OMAP3430ES2_CLKTRCTRL_USBHOST_MASK
,
361 static struct clockdomain usbhost_am35x_clkdm
= {
362 .name
= "usbhost_clkdm",
363 .pwrdm
= { .name
= "core_pwrdm" },
364 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
365 .wkdep_srcs
= usbhost_am35x_wkdeps
,
366 .sleepdep_srcs
= usbhost_am35x_sleepdeps
,
367 .clktrctrl_mask
= OMAP3430ES2_CLKTRCTRL_USBHOST_MASK
,
370 static struct clockdomain per_clkdm
= {
372 .pwrdm
= { .name
= "per_pwrdm" },
373 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
374 .dep_bit
= OMAP3430_EN_PER_SHIFT
,
375 .wkdep_srcs
= per_wkdeps
,
376 .sleepdep_srcs
= per_sleepdeps
,
377 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_PER_MASK
,
380 static struct clockdomain per_am35x_clkdm
= {
382 .pwrdm
= { .name
= "per_pwrdm" },
383 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
384 .dep_bit
= OMAP3430_EN_PER_SHIFT
,
385 .wkdep_srcs
= per_am35x_wkdeps
,
386 .sleepdep_srcs
= per_am35x_sleepdeps
,
387 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_PER_MASK
,
390 static struct clockdomain emu_clkdm
= {
392 .pwrdm
= { .name
= "emu_pwrdm" },
393 .flags
= (CLKDM_CAN_ENABLE_AUTO
| CLKDM_CAN_SWSUP
|
394 CLKDM_MISSING_IDLE_REPORTING
),
395 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_EMU_MASK
,
398 static struct clockdomain dpll1_clkdm
= {
399 .name
= "dpll1_clkdm",
400 .pwrdm
= { .name
= "dpll1_pwrdm" },
403 static struct clockdomain dpll2_clkdm
= {
404 .name
= "dpll2_clkdm",
405 .pwrdm
= { .name
= "dpll2_pwrdm" },
408 static struct clockdomain dpll3_clkdm
= {
409 .name
= "dpll3_clkdm",
410 .pwrdm
= { .name
= "dpll3_pwrdm" },
413 static struct clockdomain dpll4_clkdm
= {
414 .name
= "dpll4_clkdm",
415 .pwrdm
= { .name
= "dpll4_pwrdm" },
418 static struct clockdomain dpll5_clkdm
= {
419 .name
= "dpll5_clkdm",
420 .pwrdm
= { .name
= "dpll5_pwrdm" },
424 * Clockdomain hwsup dependencies
427 static struct clkdm_autodep clkdm_autodeps
[] = {
429 .clkdm
= { .name
= "mpu_clkdm" },
432 .clkdm
= { .name
= "iva2_clkdm" },
435 .clkdm
= { .name
= NULL
},
439 static struct clkdm_autodep clkdm_am35x_autodeps
[] = {
441 .clkdm
= { .name
= "mpu_clkdm" },
444 .clkdm
= { .name
= NULL
},
452 static struct clockdomain
*clockdomains_common
[] __initdata
= {
464 static struct clockdomain
*clockdomains_omap3430
[] __initdata
= {
475 static struct clockdomain
*clockdomains_omap3430es1
[] __initdata
= {
480 static struct clockdomain
*clockdomains_omap3430es2plus
[] __initdata
= {
487 static struct clockdomain
*clockdomains_am35x
[] __initdata
= {
492 &usbhost_am35x_clkdm
,
497 void __init
omap3xxx_clockdomains_init(void)
499 struct clockdomain
**sc
;
502 if (!cpu_is_omap34xx())
505 clkdm_register_platform_funcs(&omap3_clkdm_operations
);
506 clkdm_register_clkdms(clockdomains_common
);
510 if (rev
== AM35XX_REV_ES1_0
|| rev
== AM35XX_REV_ES1_1
) {
511 clkdm_register_clkdms(clockdomains_am35x
);
512 clkdm_register_autodeps(clkdm_am35x_autodeps
);
514 clkdm_register_clkdms(clockdomains_omap3430
);
516 sc
= (rev
== OMAP3430_REV_ES1_0
) ?
517 clockdomains_omap3430es1
: clockdomains_omap3430es2plus
;
519 clkdm_register_clkdms(sc
);
520 clkdm_register_autodeps(clkdm_autodeps
);
523 clkdm_complete_init();