Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/arm/mach-omap2/clockdomains3xxx_data.c
26292 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* OMAP3xxx clockdomains
4
*
5
* Copyright (C) 2008-2011 Texas Instruments, Inc.
6
* Copyright (C) 2008-2010 Nokia Corporation
7
*
8
* Paul Walmsley, Jouni Högander
9
*
10
* This file contains clockdomains and clockdomain wakeup/sleep
11
* dependencies for the OMAP3xxx chips. Some notes:
12
*
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).
18
*
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
22
*
23
* XXX should dep_bit be a mask, so we can test to see if it is 0 as a
24
* sanity check?
25
* XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
26
*/
27
28
/*
29
* To-Do List
30
* -> Port the Sleep/Wakeup dependencies for the domains
31
* from the Power domain framework
32
*/
33
34
#include <linux/kernel.h>
35
#include <linux/io.h>
36
37
#include "soc.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"
43
44
/*
45
* Clockdomain dependencies for wkdeps/sleepdeps
46
*
47
* XXX Hardware dependencies (e.g., dependencies that cannot be
48
* changed in software) are not included here yet, but should be.
49
*/
50
51
/* OMAP3-specific possible dependencies */
52
53
/*
54
* 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
55
* 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
56
*/
57
static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = {
58
{ .clkdm_name = "iva2_clkdm" },
59
{ .clkdm_name = "mpu_clkdm" },
60
{ .clkdm_name = "wkup_clkdm" },
61
{ NULL },
62
};
63
64
static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
65
{ .clkdm_name = "mpu_clkdm" },
66
{ .clkdm_name = "wkup_clkdm" },
67
{ NULL },
68
};
69
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" },
77
{ NULL },
78
};
79
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" },
85
{ NULL },
86
};
87
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" },
95
{ NULL },
96
};
97
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" },
103
{ NULL },
104
};
105
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" },
113
{ NULL },
114
};
115
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" },
121
{ NULL },
122
};
123
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" },
132
{ NULL },
133
};
134
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" },
140
{ NULL },
141
};
142
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" },
148
{ NULL },
149
};
150
151
static struct clkdm_dep dss_am35x_wkdeps[] = {
152
{ .clkdm_name = "mpu_clkdm" },
153
{ .clkdm_name = "wkup_clkdm" },
154
{ NULL },
155
};
156
157
/* 3430: PM_WKDEP_NEON: MPU */
158
static struct clkdm_dep neon_wkdeps[] = {
159
{ .clkdm_name = "mpu_clkdm" },
160
{ NULL },
161
};
162
163
/* Sleep dependency source arrays for OMAP3-specific clkdms */
164
165
/* 3430: CM_SLEEPDEP_DSS: MPU, IVA */
166
static struct clkdm_dep dss_sleepdeps[] = {
167
{ .clkdm_name = "mpu_clkdm" },
168
{ .clkdm_name = "iva2_clkdm" },
169
{ NULL },
170
};
171
172
static struct clkdm_dep dss_am35x_sleepdeps[] = {
173
{ .clkdm_name = "mpu_clkdm" },
174
{ NULL },
175
};
176
177
/* 3430: CM_SLEEPDEP_PER: MPU, IVA */
178
static struct clkdm_dep per_sleepdeps[] = {
179
{ .clkdm_name = "mpu_clkdm" },
180
{ .clkdm_name = "iva2_clkdm" },
181
{ NULL },
182
};
183
184
static struct clkdm_dep per_am35x_sleepdeps[] = {
185
{ .clkdm_name = "mpu_clkdm" },
186
{ NULL },
187
};
188
189
/* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
190
static struct clkdm_dep usbhost_sleepdeps[] = {
191
{ .clkdm_name = "mpu_clkdm" },
192
{ .clkdm_name = "iva2_clkdm" },
193
{ NULL },
194
};
195
196
static struct clkdm_dep usbhost_am35x_sleepdeps[] = {
197
{ .clkdm_name = "mpu_clkdm" },
198
{ NULL },
199
};
200
201
/* 3430: CM_SLEEPDEP_CAM: MPU */
202
static struct clkdm_dep cam_sleepdeps[] = {
203
{ .clkdm_name = "mpu_clkdm" },
204
{ NULL },
205
};
206
207
/*
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.
212
*/
213
static struct clkdm_dep gfx_sgx_sleepdeps[] = {
214
{ .clkdm_name = "mpu_clkdm" },
215
{ NULL },
216
};
217
218
/*
219
* OMAP3 clockdomains
220
*/
221
222
static struct clockdomain mpu_3xxx_clkdm = {
223
.name = "mpu_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,
229
};
230
231
static struct clockdomain mpu_am35x_clkdm = {
232
.name = "mpu_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,
238
};
239
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,
246
};
247
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,
255
};
256
257
static struct clockdomain gfx_3430es1_clkdm = {
258
.name = "gfx_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,
264
};
265
266
static struct clockdomain sgx_clkdm = {
267
.name = "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,
273
};
274
275
static struct clockdomain sgx_am35x_clkdm = {
276
.name = "sgx_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,
282
};
283
284
/*
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.
290
*/
291
static struct clockdomain d2d_clkdm = {
292
.name = "d2d_clkdm",
293
.pwrdm = { .name = "core_pwrdm" },
294
.flags = CLKDM_CAN_HWSUP_SWSUP,
295
.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
296
};
297
298
/*
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
302
*/
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,
309
};
310
311
/*
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
315
*/
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,
322
};
323
324
/* Another case of bit name collisions between several registers: EN_DSS */
325
static struct clockdomain dss_3xxx_clkdm = {
326
.name = "dss_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,
333
};
334
335
static struct clockdomain dss_am35x_clkdm = {
336
.name = "dss_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,
343
};
344
345
static struct clockdomain cam_clkdm = {
346
.name = "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,
352
};
353
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,
361
};
362
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,
370
};
371
372
static struct clockdomain per_clkdm = {
373
.name = "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,
380
};
381
382
static struct clockdomain per_am35x_clkdm = {
383
.name = "per_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,
390
};
391
392
static struct clockdomain emu_clkdm = {
393
.name = "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,
398
};
399
400
static struct clockdomain dpll1_clkdm = {
401
.name = "dpll1_clkdm",
402
.pwrdm = { .name = "dpll1_pwrdm" },
403
};
404
405
static struct clockdomain dpll2_clkdm = {
406
.name = "dpll2_clkdm",
407
.pwrdm = { .name = "dpll2_pwrdm" },
408
};
409
410
static struct clockdomain dpll3_clkdm = {
411
.name = "dpll3_clkdm",
412
.pwrdm = { .name = "dpll3_pwrdm" },
413
};
414
415
static struct clockdomain dpll4_clkdm = {
416
.name = "dpll4_clkdm",
417
.pwrdm = { .name = "dpll4_pwrdm" },
418
};
419
420
static struct clockdomain dpll5_clkdm = {
421
.name = "dpll5_clkdm",
422
.pwrdm = { .name = "dpll5_pwrdm" },
423
};
424
425
/*
426
* Clockdomain hwsup dependencies
427
*/
428
429
static struct clkdm_autodep clkdm_autodeps[] = {
430
{
431
.clkdm = { .name = "mpu_clkdm" },
432
},
433
{
434
.clkdm = { .name = "iva2_clkdm" },
435
},
436
{
437
.clkdm = { .name = NULL },
438
}
439
};
440
441
static struct clkdm_autodep clkdm_am35x_autodeps[] = {
442
{
443
.clkdm = { .name = "mpu_clkdm" },
444
},
445
{
446
.clkdm = { .name = NULL },
447
}
448
};
449
450
/*
451
*
452
*/
453
454
static struct clockdomain *clockdomains_common[] __initdata = {
455
&wkup_common_clkdm,
456
&neon_clkdm,
457
&core_l3_3xxx_clkdm,
458
&core_l4_3xxx_clkdm,
459
&emu_clkdm,
460
&dpll1_clkdm,
461
&dpll3_clkdm,
462
&dpll4_clkdm,
463
NULL
464
};
465
466
static struct clockdomain *clockdomains_omap3430[] __initdata = {
467
&mpu_3xxx_clkdm,
468
&iva2_clkdm,
469
&d2d_clkdm,
470
&dss_3xxx_clkdm,
471
&cam_clkdm,
472
&per_clkdm,
473
&dpll2_clkdm,
474
NULL
475
};
476
477
static struct clockdomain *clockdomains_omap3430es1[] __initdata = {
478
&gfx_3430es1_clkdm,
479
NULL,
480
};
481
482
static struct clockdomain *clockdomains_omap3430es2plus[] __initdata = {
483
&sgx_clkdm,
484
&dpll5_clkdm,
485
&usbhost_clkdm,
486
NULL,
487
};
488
489
static struct clockdomain *clockdomains_am35x[] __initdata = {
490
&mpu_am35x_clkdm,
491
&sgx_am35x_clkdm,
492
&dss_am35x_clkdm,
493
&per_am35x_clkdm,
494
&usbhost_am35x_clkdm,
495
&dpll5_clkdm,
496
NULL
497
};
498
499
void __init omap3xxx_clockdomains_init(void)
500
{
501
struct clockdomain **sc;
502
unsigned int rev;
503
504
if (!cpu_is_omap34xx())
505
return;
506
507
clkdm_register_platform_funcs(&omap3_clkdm_operations);
508
clkdm_register_clkdms(clockdomains_common);
509
510
rev = omap_rev();
511
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);
515
} else {
516
clkdm_register_clkdms(clockdomains_omap3430);
517
518
sc = (rev == OMAP3430_REV_ES1_0) ?
519
clockdomains_omap3430es1 : clockdomains_omap3430es2plus;
520
521
clkdm_register_clkdms(sc);
522
clkdm_register_autodeps(clkdm_autodeps);
523
}
524
525
clkdm_complete_init();
526
}
527
528