1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: #include "hw.h"
24: #include "omap.h"
25:
26: struct clk {
27: const char *name;
28: const char *alias;
29: struct clk *parent;
30: struct clk *child1;
31: struct clk *sibling;
32: #define ALWAYS_ENABLED (1 << 0)
33: #define CLOCK_IN_OMAP310 (1 << 10)
34: #define CLOCK_IN_OMAP730 (1 << 11)
35: #define CLOCK_IN_OMAP1510 (1 << 12)
36: #define CLOCK_IN_OMAP16XX (1 << 13)
37: uint32_t flags;
38: int id;
39:
40: int running;
41: int enabled;
42: unsigned long rate;
43: unsigned int divisor;
44: unsigned int multiplier;
45: qemu_irq users[16];
46: int usecount;
47: };
48:
49: static struct clk xtal_osc12m = {
50: .name = "xtal_osc_12m",
51: .rate = 12000000,
52: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
53: };
54:
55: static struct clk xtal_osc32k = {
56: .name = "xtal_osc_32k",
57: .rate = 32768,
58: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
59: };
60:
61: static struct clk ck_ref = {
62: .name = "ck_ref",
63: .alias = "clkin",
64: .parent = &xtal_osc12m,
65: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
66: ALWAYS_ENABLED,
67: };
68:
69:
70: static struct clk dpll1 = {
71: .name = "dpll1",
72: .parent = &ck_ref,
73: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
74: ALWAYS_ENABLED,
75: };
76:
77: static struct clk dpll2 = {
78: .name = "dpll2",
79: .parent = &ck_ref,
80: .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
81: };
82:
83: static struct clk dpll3 = {
84: .name = "dpll3",
85: .parent = &ck_ref,
86: .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
87: };
88:
89: static struct clk dpll4 = {
90: .name = "dpll4",
91: .parent = &ck_ref,
92: .multiplier = 4,
93: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
94: };
95:
96: static struct clk apll = {
97: .name = "apll",
98: .parent = &ck_ref,
99: .multiplier = 48,
100: .divisor = 12,
101: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
102: };
103:
104: static struct clk ck_48m = {
105: .name = "ck_48m",
106: .parent = &dpll4,
107: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
108: };
109:
110: static struct clk ck_dpll1out = {
111: .name = "ck_dpll1out",
112: .parent = &dpll1,
113: .flags = CLOCK_IN_OMAP16XX,
114: };
115:
116: static struct clk sossi_ck = {
117: .name = "ck_sossi",
118: .parent = &ck_dpll1out,
119: .flags = CLOCK_IN_OMAP16XX,
120: };
121:
122: static struct clk clkm1 = {
123: .name = "clkm1",
124: .alias = "ck_gen1",
125: .parent = &dpll1,
126: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
127: ALWAYS_ENABLED,
128: };
129:
130: static struct clk clkm2 = {
131: .name = "clkm2",
132: .alias = "ck_gen2",
133: .parent = &dpll1,
134: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
135: ALWAYS_ENABLED,
136: };
137:
138: static struct clk clkm3 = {
139: .name = "clkm3",
140: .alias = "ck_gen3",
141: .parent = &dpll1,
142: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
143: ALWAYS_ENABLED,
144: };
145:
146: static struct clk arm_ck = {
147: .name = "arm_ck",
148: .alias = "mpu_ck",
149: .parent = &clkm1,
150: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
151: ALWAYS_ENABLED,
152: };
153:
154: static struct clk armper_ck = {
155: .name = "armper_ck",
156: .alias = "mpuper_ck",
157: .parent = &clkm1,
158: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
159: };
160:
161: static struct clk arm_gpio_ck = {
162: .name = "arm_gpio_ck",
163: .alias = "mpu_gpio_ck",
164: .parent = &clkm1,
165: .divisor = 1,
166: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
167: };
168:
169: static struct clk armxor_ck = {
170: .name = "armxor_ck",
171: .alias = "mpuxor_ck",
172: .parent = &ck_ref,
173: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
174: };
175:
176: static struct clk armtim_ck = {
177: .name = "armtim_ck",
178: .alias = "mputim_ck",
179: .parent = &ck_ref,
180: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
181: };
182:
183: static struct clk armwdt_ck = {
184: .name = "armwdt_ck",
185: .alias = "mpuwd_ck",
186: .parent = &clkm1,
187: .divisor = 14,
188: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
189: ALWAYS_ENABLED,
190: };
191:
192: static struct clk arminth_ck16xx = {
193: .name = "arminth_ck",
194: .parent = &arm_ck,
195: .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
196:
197:
198:
199:
200:
201: };
202:
203: static struct clk dsp_ck = {
204: .name = "dsp_ck",
205: .parent = &clkm2,
206: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
207: };
208:
209: static struct clk dspmmu_ck = {
210: .name = "dspmmu_ck",
211: .parent = &clkm2,
212: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
213: ALWAYS_ENABLED,
214: };
215:
216: static struct clk dspper_ck = {
217: .name = "dspper_ck",
218: .parent = &clkm2,
219: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
220: };
221:
222: static struct clk dspxor_ck = {
223: .name = "dspxor_ck",
224: .parent = &ck_ref,
225: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
226: };
227:
228: static struct clk dsptim_ck = {
229: .name = "dsptim_ck",
230: .parent = &ck_ref,
231: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
232: };
233:
234: static struct clk tc_ck = {
235: .name = "tc_ck",
236: .parent = &clkm3,
237: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
238: CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
239: ALWAYS_ENABLED,
240: };
241:
242: static struct clk arminth_ck15xx = {
243: .name = "arminth_ck",
244: .parent = &tc_ck,
245: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
246:
247:
248:
249:
250: };
251:
252: static struct clk tipb_ck = {
253:
254: .name = "tipb_ck",
255: .parent = &tc_ck,
256: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
257: };
258:
259: static struct clk l3_ocpi_ck = {
260:
261: .name = "l3_ocpi_ck",
262: .parent = &tc_ck,
263: .flags = CLOCK_IN_OMAP16XX,
264: };
265:
266: static struct clk tc1_ck = {
267: .name = "tc1_ck",
268: .parent = &tc_ck,
269: .flags = CLOCK_IN_OMAP16XX,
270: };
271:
272: static struct clk tc2_ck = {
273: .name = "tc2_ck",
274: .parent = &tc_ck,
275: .flags = CLOCK_IN_OMAP16XX,
276: };
277:
278: static struct clk dma_ck = {
279:
280: .name = "dma_ck",
281: .parent = &tc_ck,
282: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
283: ALWAYS_ENABLED,
284: };
285:
286: static struct clk dma_lcdfree_ck = {
287: .name = "dma_lcdfree_ck",
288: .parent = &tc_ck,
289: .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
290: };
291:
292: static struct clk api_ck = {
293: .name = "api_ck",
294: .alias = "mpui_ck",
295: .parent = &tc_ck,
296: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
297: };
298:
299: static struct clk lb_ck = {
300: .name = "lb_ck",
301: .parent = &tc_ck,
302: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
303: };
304:
305: static struct clk lbfree_ck = {
306: .name = "lbfree_ck",
307: .parent = &tc_ck,
308: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
309: };
310:
311: static struct clk hsab_ck = {
312: .name = "hsab_ck",
313: .parent = &tc_ck,
314: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
315: };
316:
317: static struct clk rhea1_ck = {
318: .name = "rhea1_ck",
319: .parent = &tc_ck,
320: .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
321: };
322:
323: static struct clk rhea2_ck = {
324: .name = "rhea2_ck",
325: .parent = &tc_ck,
326: .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
327: };
328:
329: static struct clk lcd_ck_16xx = {
330: .name = "lcd_ck",
331: .parent = &clkm3,
332: .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730,
333: };
334:
335: static struct clk lcd_ck_1510 = {
336: .name = "lcd_ck",
337: .parent = &clkm3,
338: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
339: };
340:
341: static struct clk uart1_1510 = {
342: .name = "uart1_ck",
343:
344: .parent = &armper_ck,
345: .rate = 12000000,
346: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
347: };
348:
349: static struct clk uart1_16xx = {
350: .name = "uart1_ck",
351:
352: .parent = &armper_ck,
353: .rate = 48000000,
354: .flags = CLOCK_IN_OMAP16XX,
355: };
356:
357: static struct clk uart2_ck = {
358: .name = "uart2_ck",
359:
360: .parent = &armper_ck,
361: .rate = 12000000,
362: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
363: ALWAYS_ENABLED,
364: };
365:
366: static struct clk uart3_1510 = {
367: .name = "uart3_ck",
368:
369: .parent = &armper_ck,
370: .rate = 12000000,
371: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
372: };
373:
374: static struct clk uart3_16xx = {
375: .name = "uart3_ck",
376:
377: .parent = &armper_ck,
378: .rate = 48000000,
379: .flags = CLOCK_IN_OMAP16XX,
380: };
381:
382: static struct clk usb_clk0 = {
383: .name = "usb_clk0",
384: .alias = "usb.clko",
385:
386: .rate = 6000000,
387: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
388: };
389:
390: static struct clk usb_hhc_ck1510 = {
391: .name = "usb_hhc_ck",
392:
393: .rate = 48000000,
394: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
395: };
396:
397: static struct clk usb_hhc_ck16xx = {
398: .name = "usb_hhc_ck",
399:
400: .rate = 48000000,
401:
402: .flags = CLOCK_IN_OMAP16XX,
403: };
404:
405: static struct clk usb_w2fc_mclk = {
406: .name = "usb_w2fc_mclk",
407: .alias = "usb_w2fc_ck",
408: .parent = &ck_48m,
409: .rate = 48000000,
410: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
411: };
412:
413: static struct clk mclk_1510 = {
414: .name = "mclk",
415:
416: .rate = 12000000,
417: .flags = CLOCK_IN_OMAP1510,
418: };
419:
420: static struct clk bclk_310 = {
421: .name = "bt_mclk_out",
422: .parent = &armper_ck,
423: .flags = CLOCK_IN_OMAP310,
424: };
425:
426: static struct clk mclk_310 = {
427: .name = "com_mclk_out",
428: .parent = &armper_ck,
429: .flags = CLOCK_IN_OMAP310,
430: };
431:
432: static struct clk mclk_16xx = {
433: .name = "mclk",
434:
435: .flags = CLOCK_IN_OMAP16XX,
436: };
437:
438: static struct clk bclk_1510 = {
439: .name = "bclk",
440:
441: .rate = 12000000,
442: .flags = CLOCK_IN_OMAP1510,
443: };
444:
445: static struct clk bclk_16xx = {
446: .name = "bclk",
447:
448: .flags = CLOCK_IN_OMAP16XX,
449: };
450:
451: static struct clk mmc1_ck = {
452: .name = "mmc_ck",
453: .id = 1,
454:
455: .parent = &armper_ck,
456: .rate = 48000000,
457: .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
458: };
459:
460: static struct clk mmc2_ck = {
461: .name = "mmc_ck",
462: .id = 2,
463:
464: .parent = &armper_ck,
465: .rate = 48000000,
466: .flags = CLOCK_IN_OMAP16XX,
467: };
468:
469: static struct clk cam_mclk = {
470: .name = "cam.mclk",
471: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
472: .rate = 12000000,
473: };
474:
475: static struct clk cam_exclk = {
476: .name = "cam.exclk",
477: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
478:
479: .parent = &cam_mclk,
480: };
481:
482: static struct clk cam_lclk = {
483: .name = "cam.lclk",
484: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
485: };
486:
487: static struct clk i2c_fck = {
488: .name = "i2c_fck",
489: .id = 1,
490: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
491: ALWAYS_ENABLED,
492: .parent = &armxor_ck,
493: };
494:
495: static struct clk i2c_ick = {
496: .name = "i2c_ick",
497: .id = 1,
498: .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
499: .parent = &armper_ck,
500: };
501:
502: static struct clk clk32k = {
503: .name = "clk32-kHz",
504: .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
505: ALWAYS_ENABLED,
506: .parent = &xtal_osc32k,
507: };
508:
509: static struct clk *onchip_clks[] = {
510:
511: &xtal_osc12m,
512: &xtal_osc32k,
513: &ck_ref,
514: &dpll1,
515: &dpll2,
516: &dpll3,
517: &dpll4,
518: &apll,
519: &ck_48m,
520:
521: &clkm1,
522: &ck_dpll1out,
523: &sossi_ck,
524: &arm_ck,
525: &armper_ck,
526: &arm_gpio_ck,
527: &armxor_ck,
528: &armtim_ck,
529: &armwdt_ck,
530: &arminth_ck15xx, &arminth_ck16xx,
531:
532: &clkm2,
533: &dsp_ck,
534: &dspmmu_ck,
535: &dspper_ck,
536: &dspxor_ck,
537: &dsptim_ck,
538:
539: &clkm3,
540: &tc_ck,
541: &tipb_ck,
542: &l3_ocpi_ck,
543: &tc1_ck,
544: &tc2_ck,
545: &dma_ck,
546: &dma_lcdfree_ck,
547: &api_ck,
548: &lb_ck,
549: &lbfree_ck,
550: &hsab_ck,
551: &rhea1_ck,
552: &rhea2_ck,
553: &lcd_ck_16xx,
554: &lcd_ck_1510,
555:
556: &uart1_1510,
557: &uart1_16xx,
558: &uart2_ck,
559: &uart3_1510,
560: &uart3_16xx,
561: &usb_clk0,
562: &usb_hhc_ck1510, &usb_hhc_ck16xx,
563: &mclk_1510, &mclk_16xx, &mclk_310,
564: &bclk_1510, &bclk_16xx, &bclk_310,
565: &mmc1_ck,
566: &mmc2_ck,
567: &cam_mclk,
568: &cam_exclk,
569: &cam_lclk,
570: &clk32k,
571: &usb_w2fc_mclk,
572:
573: &i2c_fck,
574: &i2c_ick,
575: 0
576: };
577:
578: void omap_clk_adduser(struct clk *clk, qemu_irq user)
579: {
580: qemu_irq *i;
581:
582: for (i = clk->users; *i; i ++);
583: *i = user;
584: }
585:
586:
587:
588: int omap_clk_is_idle(struct clk *clk)
589: {
590: struct clk *chld;
591:
592: if (!clk->enabled && (!clk->usecount || !(clk->flags && ALWAYS_ENABLED)))
593: return 1;
594: if (clk->usecount)
595: return 0;
596:
597: for (chld = clk->child1; chld; chld = chld->sibling)
598: if (!omap_clk_is_idle(chld))
599: return 0;
600: return 1;
601: }
602:
603: struct clk *omap_findclk(struct omap_mpu_state_s *mpu, const char *name)
604: {
605: struct clk *i;
606:
607: for (i = mpu->clks; i->name; i ++)
608: if (!strcmp(i->name, name) || (i->alias && !strcmp(i->alias, name)))
609: return i;
610: cpu_abort(mpu->env, "%s: %s not found\n", __FUNCTION__, name);
611: }
612:
613: void omap_clk_get(struct clk *clk)
614: {
615: clk->usecount ++;
616: }
617:
618: void omap_clk_put(struct clk *clk)