File:
[Qemu by Fabrice Bellard] /
qemu /
hw /
omap_clk.c
Revision
1.1.1.3 (vendor branch):
download - view:
text,
annotated -
select for diffs
Tue Apr 24 17:39:01 2018 UTC (2 years, 11 months ago) by
root
Branches:
qemu,
MAIN
CVS tags:
qemu1000,
qemu0151,
qemu0150,
qemu0141,
qemu0140,
qemu0130,
qemu0125,
qemu0124,
qemu0123,
qemu0122,
qemu0121,
qemu0120,
HEAD
qemu 0.12.0
1: /*
2: * OMAP clocks.
3: *
4: * Copyright (C) 2006-2008 Andrzej Zaborowski <balrog@zabor.org>
5: *
6: * Clocks data comes in part from arch/arm/mach-omap1/clock.h in Linux.
7: *
8: * This program is free software; you can redistribute it and/or
9: * modify it under the terms of the GNU General Public License as
10: * published by the Free Software Foundation; either version 2 of
11: * the License, or (at your option) any later version.
12: *
13: * This program is distributed in the hope that it will be useful,
14: * but WITHOUT ANY WARRANTY; without even the implied warranty of
15: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16: * GNU General Public License for more details.
17: *
18: * You should have received a copy of the GNU General Public License along
19: * with this program; if not, see <http://www.gnu.org/licenses/>.
20: */
21: #include "hw.h"
22: #include "omap.h"
23:
24: struct clk {
25: const char *name;
26: const char *alias;
27: struct clk *parent;
28: struct clk *child1;
29: struct clk *sibling;
30: #define ALWAYS_ENABLED (1 << 0)
31: #define CLOCK_IN_OMAP310 (1 << 10)
32: #define CLOCK_IN_OMAP730 (1 << 11)
33: #define CLOCK_IN_OMAP1510 (1 << 12)
34: #define CLOCK_IN_OMAP16XX (1 << 13)
35: #define CLOCK_IN_OMAP242X (1 << 14)
36: #define CLOCK_IN_OMAP243X (1 << 15)
37: #define CLOCK_IN_OMAP343X (1 << 16)
38: uint32_t flags;
39: int id;
40:
41: int running; /* Is currently ticking */
42: int enabled; /* Is enabled, regardless of its input clk */
43: unsigned long rate; /* Current rate (if .running) */
44: unsigned int divisor; /* Rate relative to input (if .enabled) */
45: unsigned int multiplier; /* Rate relative to input (if .enabled) */
46: qemu_irq users[16]; /* Who to notify on change */
47: int usecount; /* Automatically idle when unused */
48: };
49:
50: static struct clk xtal_osc12m = {
51: .name = "xtal_osc_12m",
52: .rate = 12000000,
53: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
54: };
55:
56: static struct clk xtal_osc32k = {
57: .name = "xtal_osc_32k",
58: .rate = 32768,
59: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
60: CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
61: };
62:
63: static struct clk ck_ref = {
64: .name = "ck_ref",
65: .alias = "clkin",
66: .parent = &xtal_osc12m,
67: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
68: ALWAYS_ENABLED,
69: };
70:
71: /* If a dpll is disabled it becomes a bypass, child clocks don't stop */
72: static struct clk dpll1 = {
73: .name = "dpll1",
74: .parent = &ck_ref,
75: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
76: ALWAYS_ENABLED,
77: };
78:
79: static struct clk dpll2 = {
80: .name = "dpll2",
81: .parent = &ck_ref,
82: .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
83: };
84:
85: static struct clk dpll3 = {
86: .name = "dpll3",
87: .parent = &ck_ref,
88: .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
89: };
90:
91: static struct clk dpll4 = {
92: .name = "dpll4",
93: .parent = &ck_ref,
94: .multiplier = 4,
95: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
96: };
97:
98: static struct clk apll = {
99: .name = "apll",
100: .parent = &ck_ref,
101: .multiplier = 48,
102: .divisor = 12,
103: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
104: };
105:
106: static struct clk ck_48m = {
107: .name = "ck_48m",
108: .parent = &dpll4, /* either dpll4 or apll */
109: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
110: };
111:
112: static struct clk ck_dpll1out = {
113: .name = "ck_dpll1out",
114: .parent = &dpll1,
115: .flags = CLOCK_IN_OMAP16XX,
116: };
117:
118: static struct clk sossi_ck = {
119: .name = "ck_sossi",
120: .parent = &ck_dpll1out,
121: .flags = CLOCK_IN_OMAP16XX,
122: };
123:
124: static struct clk clkm1 = {
125: .name = "clkm1",
126: .alias = "ck_gen1",
127: .parent = &dpll1,
128: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
129: ALWAYS_ENABLED,
130: };
131:
132: static struct clk clkm2 = {
133: .name = "clkm2",
134: .alias = "ck_gen2",
135: .parent = &dpll1,
136: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
137: ALWAYS_ENABLED,
138: };
139:
140: static struct clk clkm3 = {
141: .name = "clkm3",
142: .alias = "ck_gen3",
143: .parent = &dpll1, /* either dpll1 or ck_ref */
144: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
145: ALWAYS_ENABLED,
146: };
147:
148: static struct clk arm_ck = {
149: .name = "arm_ck",
150: .alias = "mpu_ck",
151: .parent = &clkm1,
152: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
153: ALWAYS_ENABLED,
154: };
155:
156: static struct clk armper_ck = {
157: .name = "armper_ck",
158: .alias = "mpuper_ck",
159: .parent = &clkm1,
160: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
161: };
162:
163: static struct clk arm_gpio_ck = {
164: .name = "arm_gpio_ck",
165: .alias = "mpu_gpio_ck",
166: .parent = &clkm1,
167: .divisor = 1,
168: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
169: };
170:
171: static struct clk armxor_ck = {
172: .name = "armxor_ck",
173: .alias = "mpuxor_ck",
174: .parent = &ck_ref,
175: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
176: };
177:
178: static struct clk armtim_ck = {
179: .name = "armtim_ck",
180: .alias = "mputim_ck",
181: .parent = &ck_ref, /* either CLKIN or DPLL1 */
182: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
183: };
184:
185: static struct clk armwdt_ck = {
186: .name = "armwdt_ck",
187: .alias = "mpuwd_ck",
188: .parent = &clkm1,
189: .divisor = 14,
190: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
191: ALWAYS_ENABLED,
192: };
193:
194: static struct clk arminth_ck16xx = {
195: .name = "arminth_ck",
196: .parent = &arm_ck,
197: .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
198: /* Note: On 16xx the frequency can be divided by 2 by programming
199: * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
200: *
201: * 1510 version is in TC clocks.
202: */
203: };
204:
205: static struct clk dsp_ck = {
206: .name = "dsp_ck",
207: .parent = &clkm2,
208: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
209: };
210:
211: static struct clk dspmmu_ck = {
212: .name = "dspmmu_ck",
213: .parent = &clkm2,
214: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
215: ALWAYS_ENABLED,
216: };
217:
218: static struct clk dspper_ck = {
219: .name = "dspper_ck",
220: .parent = &clkm2,
221: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
222: };
223:
224: static struct clk dspxor_ck = {
225: .name = "dspxor_ck",
226: .parent = &ck_ref,
227: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
228: };
229:
230: static struct clk dsptim_ck = {
231: .name = "dsptim_ck",
232: .parent = &ck_ref,
233: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
234: };
235:
236: static struct clk tc_ck = {
237: .name = "tc_ck",
238: .parent = &clkm3,
239: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
240: CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
241: ALWAYS_ENABLED,
242: };
243:
244: static struct clk arminth_ck15xx = {
245: .name = "arminth_ck",
246: .parent = &tc_ck,
247: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
248: /* Note: On 1510 the frequency follows TC_CK
249: *
250: * 16xx version is in MPU clocks.
251: */
252: };
253:
254: static struct clk tipb_ck = {
255: /* No-idle controlled by "tc_ck" */
256: .name = "tipb_ck",
257: .parent = &tc_ck,
258: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
259: };
260:
261: static struct clk l3_ocpi_ck = {
262: /* No-idle controlled by "tc_ck" */
263: .name = "l3_ocpi_ck",
264: .parent = &tc_ck,
265: .flags = CLOCK_IN_OMAP16XX,
266: };
267:
268: static struct clk tc1_ck = {
269: .name = "tc1_ck",
270: .parent = &tc_ck,
271: .flags = CLOCK_IN_OMAP16XX,
272: };
273:
274: static struct clk tc2_ck = {
275: .name = "tc2_ck",
276: .parent = &tc_ck,
277: .flags = CLOCK_IN_OMAP16XX,
278: };
279:
280: static struct clk dma_ck = {
281: /* No-idle controlled by "tc_ck" */
282: .name = "dma_ck",
283: .parent = &tc_ck,
284: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
285: ALWAYS_ENABLED,
286: };
287:
288: static struct clk dma_lcdfree_ck = {
289: .name = "dma_lcdfree_ck",
290: .parent = &tc_ck,
291: .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
292: };
293:
294: static struct clk api_ck = {
295: .name = "api_ck",
296: .alias = "mpui_ck",
297: .parent = &tc_ck,
298: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
299: };
300:
301: static struct clk lb_ck = {
302: .name = "lb_ck",
303: .parent = &tc_ck,
304: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
305: };
306:
307: static struct clk lbfree_ck = {
308: .name = "lbfree_ck",
309: .parent = &tc_ck,
310: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
311: };
312:
313: static struct clk hsab_ck = {
314: .name = "hsab_ck",
315: .parent = &tc_ck,
316: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
317: };
318:
319: static struct clk rhea1_ck = {
320: .name = "rhea1_ck",
321: .parent = &tc_ck,
322: .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
323: };
324:
325: static struct clk rhea2_ck = {
326: .name = "rhea2_ck",
327: .parent = &tc_ck,
328: .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
329: };
330:
331: static struct clk lcd_ck_16xx = {
332: .name = "lcd_ck",
333: .parent = &clkm3,
334: .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730,
335: };
336:
337: static struct clk lcd_ck_1510 = {
338: .name = "lcd_ck",
339: .parent = &clkm3,
340: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
341: };
342:
343: static struct clk uart1_1510 = {
344: .name = "uart1_ck",
345: /* Direct from ULPD, no real parent */
346: .parent = &armper_ck, /* either armper_ck or dpll4 */
347: .rate = 12000000,
348: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
349: };
350:
351: static struct clk uart1_16xx = {
352: .name = "uart1_ck",
353: /* Direct from ULPD, no real parent */
354: .parent = &armper_ck,
355: .rate = 48000000,
356: .flags = CLOCK_IN_OMAP16XX,
357: };
358:
359: static struct clk uart2_ck = {
360: .name = "uart2_ck",
361: /* Direct from ULPD, no real parent */
362: .parent = &armper_ck, /* either armper_ck or dpll4 */
363: .rate = 12000000,
364: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
365: ALWAYS_ENABLED,
366: };
367:
368: static struct clk uart3_1510 = {
369: .name = "uart3_ck",
370: /* Direct from ULPD, no real parent */
371: .parent = &armper_ck, /* either armper_ck or dpll4 */
372: .rate = 12000000,
373: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
374: };
375:
376: static struct clk uart3_16xx = {
377: .name = "uart3_ck",
378: /* Direct from ULPD, no real parent */
379: .parent = &armper_ck,
380: .rate = 48000000,
381: .flags = CLOCK_IN_OMAP16XX,
382: };
383:
384: static struct clk usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */
385: .name = "usb_clk0",
386: .alias = "usb.clko",
387: /* Direct from ULPD, no parent */
388: .rate = 6000000,
389: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
390: };
391:
392: static struct clk usb_hhc_ck1510 = {
393: .name = "usb_hhc_ck",
394: /* Direct from ULPD, no parent */
395: .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
396: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
397: };
398:
399: static struct clk usb_hhc_ck16xx = {
400: .name = "usb_hhc_ck",
401: /* Direct from ULPD, no parent */
402: .rate = 48000000,
403: /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
404: .flags = CLOCK_IN_OMAP16XX,
405: };
406:
407: static struct clk usb_w2fc_mclk = {
408: .name = "usb_w2fc_mclk",
409: .alias = "usb_w2fc_ck",
410: .parent = &ck_48m,
411: .rate = 48000000,
412: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
413: };
414:
415: static struct clk mclk_1510 = {
416: .name = "mclk",
417: /* Direct from ULPD, no parent. May be enabled by ext hardware. */
418: .rate = 12000000,
419: .flags = CLOCK_IN_OMAP1510,
420: };
421:
422: static struct clk bclk_310 = {
423: .name = "bt_mclk_out", /* Alias midi_mclk_out? */
424: .parent = &armper_ck,
425: .flags = CLOCK_IN_OMAP310,
426: };
427:
428: static struct clk mclk_310 = {
429: .name = "com_mclk_out",
430: .parent = &armper_ck,
431: .flags = CLOCK_IN_OMAP310,
432: };
433:
434: static struct clk mclk_16xx = {
435: .name = "mclk",
436: /* Direct from ULPD, no parent. May be enabled by ext hardware. */
437: .flags = CLOCK_IN_OMAP16XX,
438: };
439:
440: static struct clk bclk_1510 = {
441: .name = "bclk",
442: /* Direct from ULPD, no parent. May be enabled by ext hardware. */
443: .rate = 12000000,
444: .flags = CLOCK_IN_OMAP1510,
445: };
446:
447: static struct clk bclk_16xx = {
448: .name = "bclk",
449: /* Direct from ULPD, no parent. May be enabled by ext hardware. */
450: .flags = CLOCK_IN_OMAP16XX,
451: };
452:
453: static struct clk mmc1_ck = {
454: .name = "mmc_ck",
455: .id = 1,
456: /* Functional clock is direct from ULPD, interface clock is ARMPER */
457: .parent = &armper_ck, /* either armper_ck or dpll4 */
458: .rate = 48000000,
459: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
460: };
461:
462: static struct clk mmc2_ck = {
463: .name = "mmc_ck",
464: .id = 2,
465: /* Functional clock is direct from ULPD, interface clock is ARMPER */
466: .parent = &armper_ck,
467: .rate = 48000000,
468: .flags = CLOCK_IN_OMAP16XX,
469: };
470:
471: static struct clk cam_mclk = {
472: .name = "cam.mclk",
473: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
474: .rate = 12000000,
475: };
476:
477: static struct clk cam_exclk = {
478: .name = "cam.exclk",
479: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
480: /* Either 12M from cam.mclk or 48M from dpll4 */
481: .parent = &cam_mclk,
482: };
483:
484: static struct clk cam_lclk = {
485: .name = "cam.lclk",
486: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
487: };
488:
489: static struct clk i2c_fck = {
490: .name = "i2c_fck",
491: .id = 1,
492: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
493: ALWAYS_ENABLED,
494: .parent = &armxor_ck,
495: };
496:
497: static struct clk i2c_ick = {
498: .name = "i2c_ick",
499: .id = 1,
500: .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
501: .parent = &armper_ck,
502: };
503:
504: static struct clk clk32k = {
505: .name = "clk32-kHz",
506: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
507: CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
508: .parent = &xtal_osc32k,
509: };
510:
511: static struct clk ref_clk = {
512: .name = "ref_clk",
513: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
514: .rate = 12000000, /* 12 MHz or 13 MHz or 19.2 MHz */
515: /*.parent = sys.xtalin */
516: };
517:
518: static struct clk apll_96m = {
519: .name = "apll_96m",
520: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
521: .rate = 96000000,
522: /*.parent = ref_clk */
523: };
524:
525: static struct clk apll_54m = {
526: .name = "apll_54m",
527: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
528: .rate = 54000000,
529: /*.parent = ref_clk */
530: };
531:
532: static struct clk sys_clk = {
533: .name = "sys_clk",
534: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
535: .rate = 32768,
536: /*.parent = sys.xtalin */
537: };
538:
539: static struct clk sleep_clk = {
540: .name = "sleep_clk",
541: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
542: .rate = 32768,
543: /*.parent = sys.xtalin */
544: };
545:
546: static struct clk dpll_ck = {
547: .name = "dpll",
548: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
549: .parent = &ref_clk,
550: };
551:
552: static struct clk dpll_x2_ck = {
553: .name = "dpll_x2",
554: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
555: .parent = &ref_clk,
556: };
557:
558: static struct clk wdt1_sys_clk = {
559: .name = "wdt1_sys_clk",
560: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
561: .rate = 32768,
562: /*.parent = sys.xtalin */
563: };
564:
565: static struct clk func_96m_clk = {
566: .name = "func_96m_clk",
567: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
568: .divisor = 1,
569: .parent = &apll_96m,
570: };
571:
572: static struct clk func_48m_clk = {
573: .name = "func_48m_clk",
574: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
575: .divisor = 2,
576: .parent = &apll_96m,
577: };
578:
579: static struct clk func_12m_clk = {
580: .name = "func_12m_clk",
581: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
582: .divisor = 8,
583: .parent = &apll_96m,
584: };
585:
586: static struct clk func_54m_clk = {
587: .name = "func_54m_clk",
588: .flags = CLOCK_IN_OMAP242X,
589: .divisor = 1,
590: .parent = &apll_54m,
591: };
592:
593: static struct clk sys_clkout = {
594: .name = "clkout",
595: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
596: .parent = &sys_clk,
597: };
598:
599: static struct clk sys_clkout2 = {
600: .name = "clkout2",
601: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
602: .parent = &sys_clk,
603: };
604:
605: static struct clk core_clk = {
606: .name = "core_clk",
607: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
608: .parent = &dpll_x2_ck, /* Switchable between dpll_ck and clk32k */
609: };
610:
611: static struct clk l3_clk = {
612: .name = "l3_clk",
613: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
614: .parent = &core_clk,
615: };
616:
617: static struct clk core_l4_iclk = {
618: .name = "core_l4_iclk",
619: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
620: .parent = &l3_clk,
621: };
622:
623: static struct clk wu_l4_iclk = {
624: .name = "wu_l4_iclk",
625: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
626: .parent = &l3_clk,
627: };
628:
629: static struct clk core_l3_iclk = {
630: .name = "core_l3_iclk",
631: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
632: .parent = &core_clk,
633: };
634:
635: static struct clk core_l4_usb_clk = {
636: .name = "core_l4_usb_clk",
637: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
638: .parent = &l3_clk,
639: };
640:
641: static struct clk wu_gpt1_clk = {
642: .name = "wu_gpt1_clk",
643: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
644: .parent = &sys_clk,
645: };
646:
647: static struct clk wu_32k_clk = {
648: .name = "wu_32k_clk",
649: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
650: .parent = &sys_clk,
651: };
652:
653: static struct clk uart1_fclk = {
654: .name = "uart1_fclk",
655: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
656: .parent = &func_48m_clk,
657: };
658:
659: static struct clk uart1_iclk = {
660: .name = "uart1_iclk",
661: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
662: .parent = &core_l4_iclk,
663: };
664:
665: static struct clk uart2_fclk = {
666: .name = "uart2_fclk",
667: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
668: .parent = &func_48m_clk,
669: };
670:
671: static struct clk uart2_iclk = {
672: .name = "uart2_iclk",
673: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
674: .parent = &core_l4_iclk,
675: };
676:
677: static struct clk uart3_fclk = {
678: .name = "uart3_fclk",
679: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
680: .parent = &func_48m_clk,
681: };
682:
683: static struct clk uart3_iclk = {
684: .name = "uart3_iclk",
685: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
686: .parent = &core_l4_iclk,
687: };
688:
689: static struct clk mpu_fclk = {
690: .name = "mpu_fclk",
691: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
692: .parent = &core_clk,
693: };
694:
695: static struct clk mpu_iclk = {
696: .name = "mpu_iclk",
697: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
698: .parent = &core_clk,
699: };
700:
701: static struct clk int_m_fclk = {
702: .name = "int_m_fclk",
703: .alias = "mpu_intc_fclk",
704: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
705: .parent = &core_clk,
706: };
707:
708: static struct clk int_m_iclk = {
709: .name = "int_m_iclk",
710: .alias = "mpu_intc_iclk",
711: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
712: .parent = &core_clk,
713: };
714:
715: static struct clk core_gpt2_clk = {
716: .name = "core_gpt2_clk",
717: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
718: .parent = &sys_clk,
719: };
720:
721: static struct clk core_gpt3_clk = {
722: .name = "core_gpt3_clk",
723: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
724: .parent = &sys_clk,
725: };
726:
727: static struct clk core_gpt4_clk = {
728: .name = "core_gpt4_clk",
729: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
730: .parent = &sys_clk,
731: };
732:
733: static struct clk core_gpt5_clk = {
734: .name = "core_gpt5_clk",
735: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
736: .parent = &sys_clk,
737: };
738:
739: static struct clk core_gpt6_clk = {
740: .name = "core_gpt6_clk",
741: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
742: .parent = &sys_clk,
743: };
744:
745: static struct clk core_gpt7_clk = {
746: .name = "core_gpt7_clk",
747: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
748: .parent = &sys_clk,
749: };
750:
751: static struct clk core_gpt8_clk = {
752: .name = "core_gpt8_clk",
753: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
754: .parent = &sys_clk,
755: };
756:
757: static struct clk core_gpt9_clk = {
758: .name = "core_gpt9_clk",
759: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
760: .parent = &sys_clk,
761: };
762:
763: static struct clk core_gpt10_clk = {
764: .name = "core_gpt10_clk",
765: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
766: .parent = &sys_clk,
767: };
768:
769: static struct clk core_gpt11_clk = {
770: .name = "core_gpt11_clk",
771: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
772: .parent = &sys_clk,
773: };
774:
775: static struct clk core_gpt12_clk = {
776: .name = "core_gpt12_clk",
777: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
778: .parent = &sys_clk,
779: };
780:
781: static struct clk mcbsp1_clk = {
782: .name = "mcbsp1_cg",
783: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
784: .divisor = 2,
785: .parent = &func_96m_clk,
786: };
787:
788: static struct clk mcbsp2_clk = {
789: .name = "mcbsp2_cg",
790: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
791: .divisor = 2,
792: .parent = &func_96m_clk,
793: };
794:
795: static struct clk emul_clk = {
796: .name = "emul_ck",
797: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
798: .parent = &func_54m_clk,
799: };
800:
801: static struct clk sdma_fclk = {
802: .name = "sdma_fclk",
803: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
804: .parent = &l3_clk,
805: };
806:
807: static struct clk sdma_iclk = {
808: .name = "sdma_iclk",
809: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
810: .parent = &core_l3_iclk, /* core_l4_iclk for the configuration port */
811: };
812:
813: static struct clk i2c1_fclk = {
814: .name = "i2c1.fclk",
815: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
816: .parent = &func_12m_clk,
817: .divisor = 1,
818: };
819:
820: static struct clk i2c1_iclk = {
821: .name = "i2c1.iclk",
822: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
823: .parent = &core_l4_iclk,
824: };
825:
826: static struct clk i2c2_fclk = {
827: .name = "i2c2.fclk",
828: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
829: .parent = &func_12m_clk,
830: .divisor = 1,
831: };
832:
833: static struct clk i2c2_iclk = {
834: .name = "i2c2.iclk",
835: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
836: .parent = &core_l4_iclk,
837: };
838:
839: static struct clk gpio_dbclk[4] = {
840: {
841: .name = "gpio1_dbclk",
842: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
843: .parent = &wu_32k_clk,
844: }, {
845: .name = "gpio2_dbclk",
846: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
847: .parent = &wu_32k_clk,
848: }, {
849: .name = "gpio3_dbclk",
850: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
851: .parent = &wu_32k_clk,
852: }, {
853: .name = "gpio4_dbclk",
854: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
855: .parent = &wu_32k_clk,
856: },
857: };
858:
859: static struct clk gpio_iclk = {
860: .name = "gpio_iclk",
861: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
862: .parent = &wu_l4_iclk,
863: };
864:
865: static struct clk mmc_fck = {
866: .name = "mmc_fclk",
867: .flags = CLOCK_IN_OMAP242X,
868: .parent = &func_96m_clk,
869: };
870:
871: static struct clk mmc_ick = {
872: .name = "mmc_iclk",
873: .flags = CLOCK_IN_OMAP242X,
874: .parent = &core_l4_iclk,
875: };
876:
877: static struct clk spi_fclk[3] = {
878: {
879: .name = "spi1_fclk",
880: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
881: .parent = &func_48m_clk,
882: }, {
883: .name = "spi2_fclk",
884: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
885: .parent = &func_48m_clk,
886: }, {
887: .name = "spi3_fclk",
888: .flags = CLOCK_IN_OMAP243X,
889: .parent = &func_48m_clk,
890: },
891: };
892:
893: static struct clk dss_clk[2] = {
894: {
895: .name = "dss_clk1",
896: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
897: .parent = &core_clk,
898: }, {
899: .name = "dss_clk2",
900: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
901: .parent = &sys_clk,
902: },
903: };
904:
905: static struct clk dss_54m_clk = {
906: .name = "dss_54m_clk",
907: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
908: .parent = &func_54m_clk,
909: };
910:
911: static struct clk dss_l3_iclk = {
912: .name = "dss_l3_iclk",
913: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
914: .parent = &core_l3_iclk,
915: };
916:
917: static struct clk dss_l4_iclk = {
918: .name = "dss_l4_iclk",
919: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
920: .parent = &core_l4_iclk,
921: };
922:
923: static struct clk spi_iclk[3] = {
924: {
925: .name = "spi1_iclk",
926: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
927: .parent = &core_l4_iclk,
928: }, {
929: .name = "spi2_iclk",
930: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
931: .parent = &core_l4_iclk,
932: }, {
933: .name = "spi3_iclk",
934: .flags = CLOCK_IN_OMAP243X,
935: .parent = &core_l4_iclk,
936: },
937: };
938:
939: static struct clk omapctrl_clk = {
940: .name = "omapctrl_iclk",
941: .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
942: /* XXX Should be in WKUP domain */
943: .parent = &core_l4_iclk,
944: };
945:
946: static struct clk *onchip_clks[] = {
947: /* OMAP 1 */
948:
949: /* non-ULPD clocks */
950: &xtal_osc12m,
951: &xtal_osc32k,
952: &ck_ref,
953: &dpll1,
954: &dpll2,
955: &dpll3,
956: &dpll4,
957: &apll,
958: &ck_48m,
959: /* CK_GEN1 clocks */
960: &clkm1,
961: &ck_dpll1out,
962: &sossi_ck,
963: &arm_ck,
964: &armper_ck,
965: &arm_gpio_ck,
966: &armxor_ck,
967: &armtim_ck,
968: &armwdt_ck,
969: &arminth_ck15xx, &arminth_ck16xx,
970: /* CK_GEN2 clocks */
971: &clkm2,
972: &dsp_ck,
973: &dspmmu_ck,
974: &dspper_ck,
975: &dspxor_ck,
976: &dsptim_ck,
977: /* CK_GEN3 clocks */
978: &clkm3,
979: &tc_ck,
980: &tipb_ck,
981: &l3_ocpi_ck,
982: &tc1_ck,
983: &tc2_ck,
984: &dma_ck,
985: &dma_lcdfree_ck,
986: &api_ck,
987: &lb_ck,
988: &lbfree_ck,
989: &hsab_ck,
990: &rhea1_ck,
991: &rhea2_ck,
992: &lcd_ck_16xx,
993: &lcd_ck_1510,
994: /* ULPD clocks */
995: &uart1_1510,
996: &uart1_16xx,
997: &uart2_ck,
998: &uart3_1510,
999: &uart3_16xx,
1000: &usb_clk0,
1001: &usb_hhc_ck1510, &usb_hhc_ck16xx,
1002: &mclk_1510, &mclk_16xx, &mclk_310,
1003: &bclk_1510, &bclk_16xx, &bclk_310,
1004: &mmc1_ck,
1005: &mmc2_ck,
1006: &cam_mclk,
1007: &cam_exclk,
1008: &cam_lclk,
1009: &clk32k,
1010: &usb_w2fc_mclk,
1011: /* Virtual clocks */
1012: &i2c_fck,
1013: &i2c_ick,
1014:
1015: /* OMAP 2 */
1016:
1017: &ref_clk,
1018: &apll_96m,
1019: &apll_54m,
1020: &sys_clk,
1021: &sleep_clk,
1022: &dpll_ck,
1023: &dpll_x2_ck,
1024: &wdt1_sys_clk,
1025: &func_96m_clk,
1026: &func_48m_clk,
1027: &func_12m_clk,
1028: &func_54m_clk,
1029: &sys_clkout,
1030: &sys_clkout2,
1031: &core_clk,
1032: &l3_clk,
1033: &core_l4_iclk,
1034: &wu_l4_iclk,
1035: &core_l3_iclk,
1036: &core_l4_usb_clk,
1037: &wu_gpt1_clk,
1038: &wu_32k_clk,
1039: &uart1_fclk,
1040: &uart1_iclk,
1041: &uart2_fclk,
1042: &uart2_iclk,
1043: &uart3_fclk,
1044: &uart3_iclk,
1045: &mpu_fclk,
1046: &mpu_iclk,
1047: &int_m_fclk,
1048: &int_m_iclk,
1049: &core_gpt2_clk,
1050: &core_gpt3_clk,
1051: &core_gpt4_clk,
1052: &core_gpt5_clk,
1053: &core_gpt6_clk,
1054: &core_gpt7_clk,
1055: &core_gpt8_clk,
1056: &core_gpt9_clk,
1057: &core_gpt10_clk,
1058: &core_gpt11_clk,
1059: &core_gpt12_clk,
1060: &mcbsp1_clk,
1061: &mcbsp2_clk,
1062: &emul_clk,
1063: &sdma_fclk,
1064: &sdma_iclk,
1065: &i2c1_fclk,
1066: &i2c1_iclk,
1067: &i2c2_fclk,
1068: &i2c2_iclk,
1069: &gpio_dbclk[0],
1070: &gpio_dbclk[1],
1071: &gpio_dbclk[2],
1072: &gpio_dbclk[3],
1073: &gpio_iclk,
1074: &mmc_fck,
1075: &mmc_ick,
1076: &spi_fclk[0],
1077: &spi_iclk[0],
1078: &spi_fclk[1],
1079: &spi_iclk[1],
1080: &spi_fclk[2],
1081: &spi_iclk[2],
1082: &dss_clk[0],
1083: &dss_clk[1],
1084: &dss_54m_clk,
1085: &dss_l3_iclk,
1086: &dss_l4_iclk,
1087: &omapctrl_clk,
1088:
1089: NULL
1090: };
1091:
1092: void omap_clk_adduser(struct clk *clk, qemu_irq user)
1093: {
1094: qemu_irq *i;
1095:
1096: for (i = clk->users; *i; i ++);
1097: *i = user;
1098: }
1099:
1100: struct clk *omap_findclk(struct omap_mpu_state_s *mpu, const char *name)
1101: {
1102: struct clk *i;
1103:
1104: for (i = mpu->clks; i->name; i ++)
1105: if (!strcmp(i->name, name) || (i->alias && !strcmp(i->alias, name)))
1106: return i;
1107: hw_error("%s: %s not found\n", __FUNCTION__, name);
1108: }
1109:
1110: void omap_clk_get(struct clk *clk)
1111: {
1112: clk->usecount ++;
1113: }
1114:
1115: void omap_clk_put(struct clk *clk)
1116: {
1117: if (!(clk->usecount --))
1118: hw_error("%s: %s is not in use\n", __FUNCTION__, clk->name);
1119: }
1120:
1121: static void omap_clk_update(struct clk *clk)
1122: {
1123: int parent, running;
1124: qemu_irq *user;
1125: struct clk *i;
1126:
1127: if (clk->parent)
1128: parent = clk->parent->running;
1129: else
1130: parent = 1;
1131:
1132: running = parent && (clk->enabled ||
1133: ((clk->flags & ALWAYS_ENABLED) && clk->usecount));
1134: if (clk->running != running) {
1135: clk->running = running;
1136: for (user = clk->users; *user; user ++)
1137: qemu_set_irq(*user, running);
1138: for (i = clk->child1; i; i = i->sibling)
1139: omap_clk_update(i);
1140: }
1141: }
1142:
1143: static void omap_clk_rate_update_full(struct clk *clk, unsigned long int rate,
1144: unsigned long int div, unsigned long int mult)
1145: {
1146: struct clk *i;
1147: qemu_irq *user;
1148:
1149: clk->rate = muldiv64(rate, mult, div);
1150: if (clk->running)
1151: for (user = clk->users; *user; user ++)
1152: qemu_irq_raise(*user);
1153: for (i = clk->child1; i; i = i->sibling)
1154: omap_clk_rate_update_full(i, rate,
1155: div * i->divisor, mult * i->multiplier);
1156: }
1157:
1158: static void omap_clk_rate_update(struct clk *clk)
1159: {
1160: struct clk *i;
1161: unsigned long int div, mult = div = 1;
1162:
1163: for (i = clk; i->parent; i = i->parent) {
1164: div *= i->divisor;
1165: mult *= i->multiplier;
1166: }
1167:
1168: omap_clk_rate_update_full(clk, i->rate, div, mult);
1169: }
1170:
1171: void omap_clk_reparent(struct clk *clk, struct clk *parent)
1172: {
1173: struct clk **p;
1174:
1175: if (clk->parent) {
1176: for (p = &clk->parent->child1; *p != clk; p = &(*p)->sibling);
1177: *p = clk->sibling;
1178: }
1179:
1180: clk->parent = parent;
1181: if (parent) {
1182: clk->sibling = parent->child1;
1183: parent->child1 = clk;
1184: omap_clk_update(clk);
1185: omap_clk_rate_update(clk);
1186: } else
1187: clk->sibling = NULL;
1188: }
1189:
1190: void omap_clk_onoff(struct clk *clk, int on)
1191: {
1192: clk->enabled = on;
1193: omap_clk_update(clk);
1194: }
1195:
1196: void omap_clk_canidle(struct clk *clk, int can)
1197: {
1198: if (can)
1199: omap_clk_put(clk);
1200: else
1201: omap_clk_get(clk);
1202: }
1203:
1204: void omap_clk_setrate(struct clk *clk, int divide, int multiply)
1205: {
1206: clk->divisor = divide;
1207: clk->multiplier = multiply;
1208: omap_clk_rate_update(clk);
1209: }
1210:
1211: int64_t omap_clk_getrate(omap_clk clk)
1212: {
1213: return clk->rate;
1214: }
1215:
1216: void omap_clk_init(struct omap_mpu_state_s *mpu)
1217: {
1218: struct clk **i, *j, *k;
1219: int count;
1220: int flag;
1221:
1222: if (cpu_is_omap310(mpu))
1223: flag = CLOCK_IN_OMAP310;
1224: else if (cpu_is_omap1510(mpu))
1225: flag = CLOCK_IN_OMAP1510;
1226: else if (cpu_is_omap2410(mpu) || cpu_is_omap2420(mpu))
1227: flag = CLOCK_IN_OMAP242X;
1228: else if (cpu_is_omap2430(mpu))
1229: flag = CLOCK_IN_OMAP243X;
1230: else if (cpu_is_omap3430(mpu))
1231: flag = CLOCK_IN_OMAP243X;
1232: else
1233: return;
1234:
1235: for (i = onchip_clks, count = 0; *i; i ++)
1236: if ((*i)->flags & flag)
1237: count ++;
1238: mpu->clks = (struct clk *) qemu_mallocz(sizeof(struct clk) * (count + 1));
1239: for (i = onchip_clks, j = mpu->clks; *i; i ++)
1240: if ((*i)->flags & flag) {
1241: memcpy(j, *i, sizeof(struct clk));
1242: for (k = mpu->clks; k < j; k ++)
1243: if (j->parent && !strcmp(j->parent->name, k->name)) {
1244: j->parent = k;
1245: j->sibling = k->child1;
1246: k->child1 = j;
1247: } else if (k->parent && !strcmp(k->parent->name, j->name)) {
1248: k->parent = j;
1249: k->sibling = j->child1;
1250: j->child1 = k;
1251: }
1252: j->divisor = j->divisor ?: 1;
1253: j->multiplier = j->multiplier ?: 1;
1254: j ++;
1255: }
1256: for (j = mpu->clks; count --; j ++) {
1257: omap_clk_update(j);
1258: omap_clk_rate_update(j);
1259: }
1260: }
unix.superglobalmegacorp.com