1 // SPDX-License-Identifier: GPL-2.0
3 * OMAP3xxx clockdomains
5 * Copyright (C) 2008-2011 Texas Instruments, Inc.
6 * Copyright (C) 2008-2010 Nokia Corporation
8 * Paul Walmsley, Jouni Högander
10 * This file contains clockdomains and clockdomain wakeup/sleep
11 * dependencies for the OMAP3xxx chips. Some notes:
13 * A useful validation rule for struct clockdomain: Any clockdomain
14 * referenced by a wkdep_srcs or sleepdep_srcs array must have a
15 * dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really just
16 * software-controllable dependencies. Non-software-controllable
17 * dependencies do exist, but they are not encoded below (yet).
19 * The overly-specific dep_bit names are due to a bit name collision
20 * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
21 * value are the same for all powerdomains: 2
23 * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
25 * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
30 * -> Port the Sleep/Wakeup dependencies for the domains
31 * from the Power domain framework
34 #include <linux/kernel.h>
38 #include "clockdomain.h"
39 #include "prm2xxx_3xxx.h"
40 #include "cm2xxx_3xxx.h"
41 #include "cm-regbits-34xx.h"
42 #include "prm-regbits-34xx.h"
45 * Clockdomain dependencies for wkdeps/sleepdeps
47 * XXX Hardware dependencies (e.g., dependencies that cannot be
48 * changed in software) are not included here yet, but should be.
51 /* OMAP3-specific possible dependencies */
54 * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
55 * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
57 static struct clkdm_dep gfx_sgx_3xxx_wkdeps
[] = {
58 { .clkdm_name
= "iva2_clkdm" },
59 { .clkdm_name
= "mpu_clkdm" },
60 { .clkdm_name
= "wkup_clkdm" },
64 static struct clkdm_dep gfx_sgx_am35x_wkdeps
[] = {
65 { .clkdm_name
= "mpu_clkdm" },
66 { .clkdm_name
= "wkup_clkdm" },
70 /* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
71 static struct clkdm_dep per_wkdeps
[] = {
72 { .clkdm_name
= "core_l3_clkdm" },
73 { .clkdm_name
= "core_l4_clkdm" },
74 { .clkdm_name
= "iva2_clkdm" },
75 { .clkdm_name
= "mpu_clkdm" },
76 { .clkdm_name
= "wkup_clkdm" },
80 static struct clkdm_dep per_am35x_wkdeps
[] = {
81 { .clkdm_name
= "core_l3_clkdm" },
82 { .clkdm_name
= "core_l4_clkdm" },
83 { .clkdm_name
= "mpu_clkdm" },
84 { .clkdm_name
= "wkup_clkdm" },
88 /* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
89 static struct clkdm_dep usbhost_wkdeps
[] = {
90 { .clkdm_name
= "core_l3_clkdm" },
91 { .clkdm_name
= "core_l4_clkdm" },
92 { .clkdm_name
= "iva2_clkdm" },
93 { .clkdm_name
= "mpu_clkdm" },
94 { .clkdm_name
= "wkup_clkdm" },
98 static struct clkdm_dep usbhost_am35x_wkdeps
[] = {
99 { .clkdm_name
= "core_l3_clkdm" },
100 { .clkdm_name
= "core_l4_clkdm" },
101 { .clkdm_name
= "mpu_clkdm" },
102 { .clkdm_name
= "wkup_clkdm" },
106 /* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
107 static struct clkdm_dep mpu_3xxx_wkdeps
[] = {
108 { .clkdm_name
= "core_l3_clkdm" },
109 { .clkdm_name
= "core_l4_clkdm" },
110 { .clkdm_name
= "iva2_clkdm" },
111 { .clkdm_name
= "dss_clkdm" },
112 { .clkdm_name
= "per_clkdm" },
116 static struct clkdm_dep mpu_am35x_wkdeps
[] = {
117 { .clkdm_name
= "core_l3_clkdm" },
118 { .clkdm_name
= "core_l4_clkdm" },
119 { .clkdm_name
= "dss_clkdm" },
120 { .clkdm_name
= "per_clkdm" },
124 /* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
125 static struct clkdm_dep iva2_wkdeps
[] = {
126 { .clkdm_name
= "core_l3_clkdm" },
127 { .clkdm_name
= "core_l4_clkdm" },
128 { .clkdm_name
= "mpu_clkdm" },
129 { .clkdm_name
= "wkup_clkdm" },
130 { .clkdm_name
= "dss_clkdm" },
131 { .clkdm_name
= "per_clkdm" },
135 /* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
136 static struct clkdm_dep cam_wkdeps
[] = {
137 { .clkdm_name
= "iva2_clkdm" },
138 { .clkdm_name
= "mpu_clkdm" },
139 { .clkdm_name
= "wkup_clkdm" },
143 /* 3430 PM_WKDEP_DSS: IVA2, MPU, WKUP */
144 static struct clkdm_dep dss_wkdeps
[] = {
145 { .clkdm_name
= "iva2_clkdm" },
146 { .clkdm_name
= "mpu_clkdm" },
147 { .clkdm_name
= "wkup_clkdm" },
151 static struct clkdm_dep dss_am35x_wkdeps
[] = {
152 { .clkdm_name
= "mpu_clkdm" },
153 { .clkdm_name
= "wkup_clkdm" },
157 /* 3430: PM_WKDEP_NEON: MPU */
158 static struct clkdm_dep neon_wkdeps
[] = {
159 { .clkdm_name
= "mpu_clkdm" },
163 /* Sleep dependency source arrays for OMAP3-specific clkdms */
165 /* 3430: CM_SLEEPDEP_DSS: MPU, IVA */
166 static struct clkdm_dep dss_sleepdeps
[] = {
167 { .clkdm_name
= "mpu_clkdm" },
168 { .clkdm_name
= "iva2_clkdm" },
172 static struct clkdm_dep dss_am35x_sleepdeps
[] = {
173 { .clkdm_name
= "mpu_clkdm" },
177 /* 3430: CM_SLEEPDEP_PER: MPU, IVA */
178 static struct clkdm_dep per_sleepdeps
[] = {
179 { .clkdm_name
= "mpu_clkdm" },
180 { .clkdm_name
= "iva2_clkdm" },
184 static struct clkdm_dep per_am35x_sleepdeps
[] = {
185 { .clkdm_name
= "mpu_clkdm" },
189 /* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
190 static struct clkdm_dep usbhost_sleepdeps
[] = {
191 { .clkdm_name
= "mpu_clkdm" },
192 { .clkdm_name
= "iva2_clkdm" },
196 static struct clkdm_dep usbhost_am35x_sleepdeps
[] = {
197 { .clkdm_name
= "mpu_clkdm" },
201 /* 3430: CM_SLEEPDEP_CAM: MPU */
202 static struct clkdm_dep cam_sleepdeps
[] = {
203 { .clkdm_name
= "mpu_clkdm" },
208 * 3430ES1: CM_SLEEPDEP_GFX: MPU
209 * 3430ES2: CM_SLEEPDEP_SGX: MPU
210 * These can share data since they will never be present simultaneously
211 * on the same device.
213 static struct clkdm_dep gfx_sgx_sleepdeps
[] = {
214 { .clkdm_name
= "mpu_clkdm" },
222 static struct clockdomain mpu_3xxx_clkdm
= {
224 .pwrdm
= { .name
= "mpu_pwrdm" },
225 .flags
= CLKDM_CAN_HWSUP
| CLKDM_CAN_FORCE_WAKEUP
,
226 .dep_bit
= OMAP3430_EN_MPU_SHIFT
,
227 .wkdep_srcs
= mpu_3xxx_wkdeps
,
228 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_MPU_MASK
,
231 static struct clockdomain mpu_am35x_clkdm
= {
233 .pwrdm
= { .name
= "mpu_pwrdm" },
234 .flags
= CLKDM_CAN_HWSUP
| CLKDM_CAN_FORCE_WAKEUP
,
235 .dep_bit
= OMAP3430_EN_MPU_SHIFT
,
236 .wkdep_srcs
= mpu_am35x_wkdeps
,
237 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_MPU_MASK
,
240 static struct clockdomain neon_clkdm
= {
241 .name
= "neon_clkdm",
242 .pwrdm
= { .name
= "neon_pwrdm" },
243 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
244 .wkdep_srcs
= neon_wkdeps
,
245 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_NEON_MASK
,
248 static struct clockdomain iva2_clkdm
= {
249 .name
= "iva2_clkdm",
250 .pwrdm
= { .name
= "iva2_pwrdm" },
251 .flags
= CLKDM_CAN_SWSUP
,
252 .dep_bit
= OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT
,
253 .wkdep_srcs
= iva2_wkdeps
,
254 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_IVA2_MASK
,
257 static struct clockdomain gfx_3430es1_clkdm
= {
259 .pwrdm
= { .name
= "gfx_pwrdm" },
260 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
261 .wkdep_srcs
= gfx_sgx_3xxx_wkdeps
,
262 .sleepdep_srcs
= gfx_sgx_sleepdeps
,
263 .clktrctrl_mask
= OMAP3430ES1_CLKTRCTRL_GFX_MASK
,
266 static struct clockdomain sgx_clkdm
= {
268 .pwrdm
= { .name
= "sgx_pwrdm" },
269 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
270 .wkdep_srcs
= gfx_sgx_3xxx_wkdeps
,
271 .sleepdep_srcs
= gfx_sgx_sleepdeps
,
272 .clktrctrl_mask
= OMAP3430ES2_CLKTRCTRL_SGX_MASK
,
275 static struct clockdomain sgx_am35x_clkdm
= {
277 .pwrdm
= { .name
= "sgx_pwrdm" },
278 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
279 .wkdep_srcs
= gfx_sgx_am35x_wkdeps
,
280 .sleepdep_srcs
= gfx_sgx_sleepdeps
,
281 .clktrctrl_mask
= OMAP3430ES2_CLKTRCTRL_SGX_MASK
,
285 * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
286 * then that information was removed from the 34xx ES2+ TRM. It is
287 * unclear whether the core is still there, but the clockdomain logic
288 * is there, and must be programmed to an appropriate state if the
289 * CORE clockdomain is to become inactive.
291 static struct clockdomain d2d_clkdm
= {
293 .pwrdm
= { .name
= "core_pwrdm" },
294 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
295 .clktrctrl_mask
= OMAP3430ES1_CLKTRCTRL_D2D_MASK
,
299 * XXX add usecounting for clkdm dependencies, otherwise the presence
300 * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
301 * could cause trouble
303 static struct clockdomain core_l3_3xxx_clkdm
= {
304 .name
= "core_l3_clkdm",
305 .pwrdm
= { .name
= "core_pwrdm" },
306 .flags
= CLKDM_CAN_HWSUP
,
307 .dep_bit
= OMAP3430_EN_CORE_SHIFT
,
308 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_L3_MASK
,
312 * XXX add usecounting for clkdm dependencies, otherwise the presence
313 * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
314 * could cause trouble
316 static struct clockdomain core_l4_3xxx_clkdm
= {
317 .name
= "core_l4_clkdm",
318 .pwrdm
= { .name
= "core_pwrdm" },
319 .flags
= CLKDM_CAN_HWSUP
,
320 .dep_bit
= OMAP3430_EN_CORE_SHIFT
,
321 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_L4_MASK
,
324 /* Another case of bit name collisions between several registers: EN_DSS */
325 static struct clockdomain dss_3xxx_clkdm
= {
327 .pwrdm
= { .name
= "dss_pwrdm" },
328 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
329 .dep_bit
= OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT
,
330 .wkdep_srcs
= dss_wkdeps
,
331 .sleepdep_srcs
= dss_sleepdeps
,
332 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_DSS_MASK
,
335 static struct clockdomain dss_am35x_clkdm
= {
337 .pwrdm
= { .name
= "dss_pwrdm" },
338 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
339 .dep_bit
= OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT
,
340 .wkdep_srcs
= dss_am35x_wkdeps
,
341 .sleepdep_srcs
= dss_am35x_sleepdeps
,
342 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_DSS_MASK
,
345 static struct clockdomain cam_clkdm
= {
347 .pwrdm
= { .name
= "cam_pwrdm" },
348 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
349 .wkdep_srcs
= cam_wkdeps
,
350 .sleepdep_srcs
= cam_sleepdeps
,
351 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_CAM_MASK
,
354 static struct clockdomain usbhost_clkdm
= {
355 .name
= "usbhost_clkdm",
356 .pwrdm
= { .name
= "usbhost_pwrdm" },
357 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
358 .wkdep_srcs
= usbhost_wkdeps
,
359 .sleepdep_srcs
= usbhost_sleepdeps
,
360 .clktrctrl_mask
= OMAP3430ES2_CLKTRCTRL_USBHOST_MASK
,
363 static struct clockdomain usbhost_am35x_clkdm
= {
364 .name
= "usbhost_clkdm",
365 .pwrdm
= { .name
= "core_pwrdm" },
366 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
367 .wkdep_srcs
= usbhost_am35x_wkdeps
,
368 .sleepdep_srcs
= usbhost_am35x_sleepdeps
,
369 .clktrctrl_mask
= OMAP3430ES2_CLKTRCTRL_USBHOST_MASK
,
372 static struct clockdomain per_clkdm
= {
374 .pwrdm
= { .name
= "per_pwrdm" },
375 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
376 .dep_bit
= OMAP3430_EN_PER_SHIFT
,
377 .wkdep_srcs
= per_wkdeps
,
378 .sleepdep_srcs
= per_sleepdeps
,
379 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_PER_MASK
,
382 static struct clockdomain per_am35x_clkdm
= {
384 .pwrdm
= { .name
= "per_pwrdm" },
385 .flags
= CLKDM_CAN_HWSUP_SWSUP
,
386 .dep_bit
= OMAP3430_EN_PER_SHIFT
,
387 .wkdep_srcs
= per_am35x_wkdeps
,
388 .sleepdep_srcs
= per_am35x_sleepdeps
,
389 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_PER_MASK
,
392 static struct clockdomain emu_clkdm
= {
394 .pwrdm
= { .name
= "emu_pwrdm" },
395 .flags
= (CLKDM_CAN_ENABLE_AUTO
| CLKDM_CAN_SWSUP
|
396 CLKDM_MISSING_IDLE_REPORTING
),
397 .clktrctrl_mask
= OMAP3430_CLKTRCTRL_EMU_MASK
,
400 static struct clockdomain dpll1_clkdm
= {
401 .name
= "dpll1_clkdm",
402 .pwrdm
= { .name
= "dpll1_pwrdm" },
405 static struct clockdomain dpll2_clkdm
= {
406 .name
= "dpll2_clkdm",
407 .pwrdm
= { .name
= "dpll2_pwrdm" },
410 static struct clockdomain dpll3_clkdm
= {
411 .name
= "dpll3_clkdm",
412 .pwrdm
= { .name
= "dpll3_pwrdm" },
415 static struct clockdomain dpll4_clkdm
= {
416 .name
= "dpll4_clkdm",
417 .pwrdm
= { .name
= "dpll4_pwrdm" },
420 static struct clockdomain dpll5_clkdm
= {
421 .name
= "dpll5_clkdm",
422 .pwrdm
= { .name
= "dpll5_pwrdm" },
426 * Clockdomain hwsup dependencies
429 static struct clkdm_autodep clkdm_autodeps
[] = {
431 .clkdm
= { .name
= "mpu_clkdm" },
434 .clkdm
= { .name
= "iva2_clkdm" },
437 .clkdm
= { .name
= NULL
},
441 static struct clkdm_autodep clkdm_am35x_autodeps
[] = {
443 .clkdm
= { .name
= "mpu_clkdm" },
446 .clkdm
= { .name
= NULL
},
454 static struct clockdomain
*clockdomains_common
[] __initdata
= {
466 static struct clockdomain
*clockdomains_omap3430
[] __initdata
= {
477 static struct clockdomain
*clockdomains_omap3430es1
[] __initdata
= {
482 static struct clockdomain
*clockdomains_omap3430es2plus
[] __initdata
= {
489 static struct clockdomain
*clockdomains_am35x
[] __initdata
= {
494 &usbhost_am35x_clkdm
,
499 void __init
omap3xxx_clockdomains_init(void)
501 struct clockdomain
**sc
;
504 if (!cpu_is_omap34xx())
507 clkdm_register_platform_funcs(&omap3_clkdm_operations
);
508 clkdm_register_clkdms(clockdomains_common
);
512 if (rev
== AM35XX_REV_ES1_0
|| rev
== AM35XX_REV_ES1_1
) {
513 clkdm_register_clkdms(clockdomains_am35x
);
514 clkdm_register_autodeps(clkdm_am35x_autodeps
);
516 clkdm_register_clkdms(clockdomains_omap3430
);
518 sc
= (rev
== OMAP3430_REV_ES1_0
) ?
519 clockdomains_omap3430es1
: clockdomains_omap3430es2plus
;
521 clkdm_register_clkdms(sc
);
522 clkdm_register_autodeps(clkdm_autodeps
);
525 clkdm_complete_init();