Add PowerPC power-management state check callback.
[qemu] / hw / omap1_clk.c
1 /*
2  * OMAP clocks.
3  *
4  * Copyright (C) 2006-2007 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
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23 #include "vl.h"
24
25 struct clk {
26     const char *name;
27     const char *alias;
28     struct clk *parent;
29     struct clk *child1;
30     struct clk *sibling;
31 #define ALWAYS_ENABLED          (1 << 0)
32 #define CLOCK_IN_OMAP310        (1 << 10)
33 #define CLOCK_IN_OMAP730        (1 << 11)
34 #define CLOCK_IN_OMAP1510       (1 << 12)
35 #define CLOCK_IN_OMAP16XX       (1 << 13)
36     uint32_t flags;
37     int id;
38
39     int running;                /* Is currently ticking */
40     int enabled;                /* Is enabled, regardless of its input clk */
41     unsigned long rate;         /* Current rate (if .running) */
42     unsigned int divisor;       /* Rate relative to input (if .enabled) */
43     unsigned int multiplier;    /* Rate relative to input (if .enabled) */
44     qemu_irq users[16];         /* Who to notify on change */
45     int usecount;               /* Automatically idle when unused */
46 };
47
48 static struct clk xtal_osc12m = {
49     .name       = "xtal_osc_12m",
50     .rate       = 12000000,
51     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
52 };
53
54 static struct clk xtal_osc32k = {
55     .name       = "xtal_osc_32k",
56     .rate       = 32768,
57     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
58 };
59
60 static struct clk ck_ref = {
61     .name       = "ck_ref",
62     .alias      = "clkin",
63     .parent     = &xtal_osc12m,
64     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
65             ALWAYS_ENABLED,
66 };
67
68 /* If a dpll is disabled it becomes a bypass, child clocks don't stop */
69 static struct clk dpll1 = {
70     .name       = "dpll1",
71     .parent     = &ck_ref,
72     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
73             ALWAYS_ENABLED,
74 };
75
76 static struct clk dpll2 = {
77     .name       = "dpll2",
78     .parent     = &ck_ref,
79     .flags      = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
80 };
81
82 static struct clk dpll3 = {
83     .name       = "dpll3",
84     .parent     = &ck_ref,
85     .flags      = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
86 };
87
88 static struct clk dpll4 = {
89     .name       = "dpll4",
90     .parent     = &ck_ref,
91     .multiplier = 4,
92     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
93 };
94
95 static struct clk apll = {
96     .name       = "apll",
97     .parent     = &ck_ref,
98     .multiplier = 48,
99     .divisor    = 12,
100     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
101 };
102
103 static struct clk ck_48m = {
104     .name       = "ck_48m",
105     .parent     = &dpll4,       /* either dpll4 or apll */
106     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
107 };
108
109 static struct clk ck_dpll1out = {
110     .name       = "ck_dpll1out",
111     .parent     = &dpll1,
112     .flags      = CLOCK_IN_OMAP16XX,
113 };
114
115 static struct clk sossi_ck = {
116     .name       = "ck_sossi",
117     .parent     = &ck_dpll1out,
118     .flags      = CLOCK_IN_OMAP16XX,
119 };
120
121 static struct clk clkm1 = {
122     .name       = "clkm1",
123     .alias      = "ck_gen1",
124     .parent     = &dpll1,
125     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
126             ALWAYS_ENABLED,
127 };
128
129 static struct clk clkm2 = {
130     .name       = "clkm2",
131     .alias      = "ck_gen2",
132     .parent     = &dpll1,
133     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
134             ALWAYS_ENABLED,
135 };
136
137 static struct clk clkm3 = {
138     .name       = "clkm3",
139     .alias      = "ck_gen3",
140     .parent     = &dpll1,       /* either dpll1 or ck_ref */
141     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
142             ALWAYS_ENABLED,
143 };
144
145 static struct clk arm_ck = {
146     .name       = "arm_ck",
147     .alias      = "mpu_ck",
148     .parent     = &clkm1,
149     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
150             ALWAYS_ENABLED,
151 };
152
153 static struct clk armper_ck = {
154     .name       = "armper_ck",
155     .alias      = "mpuper_ck",
156     .parent     = &clkm1,
157     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
158 };
159
160 static struct clk arm_gpio_ck = {
161     .name       = "arm_gpio_ck",
162     .alias      = "mpu_gpio_ck",
163     .parent     = &clkm1,
164     .divisor    = 1,
165     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
166 };
167
168 static struct clk armxor_ck = {
169     .name       = "armxor_ck",
170     .alias      = "mpuxor_ck",
171     .parent     = &ck_ref,
172     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
173 };
174
175 static struct clk armtim_ck = {
176     .name       = "armtim_ck",
177     .alias      = "mputim_ck",
178     .parent     = &ck_ref,      /* either CLKIN or DPLL1 */
179     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
180 };
181
182 static struct clk armwdt_ck = {
183     .name       = "armwdt_ck",
184     .alias      = "mpuwd_ck",
185     .parent     = &clkm1,
186     .divisor    = 14,
187     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
188             ALWAYS_ENABLED,
189 };
190
191 static struct clk arminth_ck16xx = {
192     .name       = "arminth_ck",
193     .parent     = &arm_ck,
194     .flags      = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
195     /* Note: On 16xx the frequency can be divided by 2 by programming
196      * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
197      *
198      * 1510 version is in TC clocks.
199      */
200 };
201
202 static struct clk dsp_ck = {
203     .name       = "dsp_ck",
204     .parent     = &clkm2,
205     .flags      = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
206 };
207
208 static struct clk dspmmu_ck = {
209     .name       = "dspmmu_ck",
210     .parent     = &clkm2,
211     .flags      = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
212             ALWAYS_ENABLED,
213 };
214
215 static struct clk dspper_ck = {
216     .name       = "dspper_ck",
217     .parent     = &clkm2,
218     .flags      = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
219 };
220
221 static struct clk dspxor_ck = {
222     .name       = "dspxor_ck",
223     .parent     = &ck_ref,
224     .flags      = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
225 };
226
227 static struct clk dsptim_ck = {
228     .name       = "dsptim_ck",
229     .parent     = &ck_ref,
230     .flags      = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
231 };
232
233 static struct clk tc_ck = {
234     .name       = "tc_ck",
235     .parent     = &clkm3,
236     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
237             CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
238             ALWAYS_ENABLED,
239 };
240
241 static struct clk arminth_ck15xx = {
242     .name       = "arminth_ck",
243     .parent     = &tc_ck,
244     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
245     /* Note: On 1510 the frequency follows TC_CK
246      *
247      * 16xx version is in MPU clocks.
248      */
249 };
250
251 static struct clk tipb_ck = {
252     /* No-idle controlled by "tc_ck" */
253     .name       = "tipb_ck",
254     .parent     = &tc_ck,
255     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
256 };
257
258 static struct clk l3_ocpi_ck = {
259     /* No-idle controlled by "tc_ck" */
260     .name       = "l3_ocpi_ck",
261     .parent     = &tc_ck,
262     .flags      = CLOCK_IN_OMAP16XX,
263 };
264
265 static struct clk tc1_ck = {
266     .name       = "tc1_ck",
267     .parent     = &tc_ck,
268     .flags      = CLOCK_IN_OMAP16XX,
269 };
270
271 static struct clk tc2_ck = {
272     .name       = "tc2_ck",
273     .parent     = &tc_ck,
274     .flags      = CLOCK_IN_OMAP16XX,
275 };
276
277 static struct clk dma_ck = {
278     /* No-idle controlled by "tc_ck" */
279     .name       = "dma_ck",
280     .parent     = &tc_ck,
281     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
282             ALWAYS_ENABLED,
283 };
284
285 static struct clk dma_lcdfree_ck = {
286     .name       = "dma_lcdfree_ck",
287     .parent     = &tc_ck,
288     .flags      = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
289 };
290
291 static struct clk api_ck = {
292     .name       = "api_ck",
293     .alias      = "mpui_ck",
294     .parent     = &tc_ck,
295     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
296 };
297
298 static struct clk lb_ck = {
299     .name       = "lb_ck",
300     .parent     = &tc_ck,
301     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
302 };
303
304 static struct clk lbfree_ck = {
305     .name       = "lbfree_ck",
306     .parent     = &tc_ck,
307     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
308 };
309
310 static struct clk rhea1_ck = {
311     .name       = "rhea1_ck",
312     .parent     = &tc_ck,
313     .flags      = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
314 };
315
316 static struct clk rhea2_ck = {
317     .name       = "rhea2_ck",
318     .parent     = &tc_ck,
319     .flags      = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
320 };
321
322 static struct clk lcd_ck_16xx = {
323     .name       = "lcd_ck",
324     .parent     = &clkm3,
325     .flags      = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730,
326 };
327
328 static struct clk lcd_ck_1510 = {
329     .name       = "lcd_ck",
330     .parent     = &clkm3,
331     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
332 };
333
334 static struct clk uart1_1510 = {
335     .name       = "uart1_ck",
336     /* Direct from ULPD, no real parent */
337     .parent     = &armper_ck,   /* either armper_ck or dpll4 */
338     .rate       = 12000000,
339     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
340 };
341
342 static struct clk uart1_16xx = {
343     .name       = "uart1_ck",
344     /* Direct from ULPD, no real parent */
345     .parent     = &armper_ck,
346     .rate       = 48000000,
347     .flags      = CLOCK_IN_OMAP16XX,
348 };
349
350 static struct clk uart2_ck = {
351     .name       = "uart2_ck",
352     /* Direct from ULPD, no real parent */
353     .parent     = &armper_ck,   /* either armper_ck or dpll4 */
354     .rate       = 12000000,
355     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
356             ALWAYS_ENABLED,
357 };
358
359 static struct clk uart3_1510 = {
360     .name       = "uart3_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_OMAP310 | ALWAYS_ENABLED,
365 };
366
367 static struct clk uart3_16xx = {
368     .name       = "uart3_ck",
369     /* Direct from ULPD, no real parent */
370     .parent     = &armper_ck,
371     .rate       = 48000000,
372     .flags      = CLOCK_IN_OMAP16XX,
373 };
374
375 static struct clk usb_clk0 = {  /* 6 MHz output on W4_USB_CLK0 */
376     .name       = "usb_clk0",
377     .alias      = "usb.clko",
378     /* Direct from ULPD, no parent */
379     .rate       = 6000000,
380     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
381 };
382
383 static struct clk usb_hhc_ck1510 = {
384     .name       = "usb_hhc_ck",
385     /* Direct from ULPD, no parent */
386     .rate       = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
387     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
388 };
389
390 static struct clk usb_hhc_ck16xx = {
391     .name       = "usb_hhc_ck",
392     /* Direct from ULPD, no parent */
393     .rate       = 48000000,
394     /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
395     .flags      = CLOCK_IN_OMAP16XX,
396 };
397
398 static struct clk usb_dc_ck = {
399     .name       = "usb_dc_ck",
400     /* Direct from ULPD, no parent */
401     .rate       = 48000000,
402     .flags      = CLOCK_IN_OMAP16XX,
403 };
404
405 static struct clk mclk_1510 = {
406     .name       = "mclk",
407     /* Direct from ULPD, no parent. May be enabled by ext hardware. */
408     .rate       = 12000000,
409     .flags      = CLOCK_IN_OMAP1510,
410 };
411
412 static struct clk bclk_310 = {
413     .name       = "bt_mclk_out",        /* Alias midi_mclk_out? */
414     .parent     = &armper_ck,
415     .flags      = CLOCK_IN_OMAP310,
416 };
417
418 static struct clk mclk_310 = {
419     .name       = "com_mclk_out",
420     .parent     = &armper_ck,
421     .flags      = CLOCK_IN_OMAP310,
422 };
423
424 static struct clk mclk_16xx = {
425     .name       = "mclk",
426     /* Direct from ULPD, no parent. May be enabled by ext hardware. */
427     .flags      = CLOCK_IN_OMAP16XX,
428 };
429
430 static struct clk bclk_1510 = {
431     .name       = "bclk",
432     /* Direct from ULPD, no parent. May be enabled by ext hardware. */
433     .rate       = 12000000,
434     .flags      = CLOCK_IN_OMAP1510,
435 };
436
437 static struct clk bclk_16xx = {
438     .name       = "bclk",
439     /* Direct from ULPD, no parent. May be enabled by ext hardware. */
440     .flags      = CLOCK_IN_OMAP16XX,
441 };
442
443 static struct clk mmc1_ck = {
444     .name       = "mmc_ck",
445     .id         = 1,
446     /* Functional clock is direct from ULPD, interface clock is ARMPER */
447     .parent     = &armper_ck,   /* either armper_ck or dpll4 */
448     .rate       = 48000000,
449     .flags      = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
450 };
451
452 static struct clk mmc2_ck = {
453     .name       = "mmc_ck",
454     .id         = 2,
455     /* Functional clock is direct from ULPD, interface clock is ARMPER */
456     .parent     = &armper_ck,
457     .rate       = 48000000,
458     .flags      = CLOCK_IN_OMAP16XX,
459 };
460
461 static struct clk cam_mclk = {
462     .name       = "cam.mclk",
463     .flags      = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
464     .rate       = 12000000,
465 };
466
467 static struct clk cam_exclk = {
468     .name       = "cam.exclk",
469     .flags      = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
470     /* Either 12M from cam.mclk or 48M from dpll4 */
471     .parent     = &cam_mclk,
472 };
473
474 static struct clk cam_lclk = {
475     .name       = "cam.lclk",
476     .flags      = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
477 };
478
479 static struct clk i2c_fck = {
480     .name       = "i2c_fck",
481     .id         = 1,
482     .flags      = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
483             ALWAYS_ENABLED,
484     .parent     = &armxor_ck,
485 };
486
487 static struct clk i2c_ick = {
488     .name       = "i2c_ick",
489     .id         = 1,
490     .flags      = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
491     .parent     = &armper_ck,
492 };
493
494 static struct clk clk32k = {
495     .name       = "clk32-kHz",
496     .flags      = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
497             ALWAYS_ENABLED,
498     .parent     = &xtal_osc32k,
499 };
500
501 static struct clk *onchip_clks[] = {
502     /* non-ULPD clocks */
503     &xtal_osc12m,
504     &xtal_osc32k,
505     &ck_ref,
506     &dpll1,
507     &dpll2,
508     &dpll3,
509     &dpll4,
510     &apll,
511     &ck_48m,
512     /* CK_GEN1 clocks */
513     &clkm1,
514     &ck_dpll1out,
515     &sossi_ck,
516     &arm_ck,
517     &armper_ck,
518     &arm_gpio_ck,
519     &armxor_ck,
520     &armtim_ck,
521     &armwdt_ck,
522     &arminth_ck15xx,  &arminth_ck16xx,
523     /* CK_GEN2 clocks */
524     &clkm2,
525     &dsp_ck,
526     &dspmmu_ck,
527     &dspper_ck,
528     &dspxor_ck,
529     &dsptim_ck,
530     /* CK_GEN3 clocks */
531     &clkm3,
532     &tc_ck,
533     &tipb_ck,
534     &l3_ocpi_ck,
535     &tc1_ck,
536     &tc2_ck,
537     &dma_ck,
538     &dma_lcdfree_ck,
539     &api_ck,
540     &lb_ck,
541     &lbfree_ck,
542     &rhea1_ck,
543     &rhea2_ck,
544     &lcd_ck_16xx,
545     &lcd_ck_1510,
546     /* ULPD clocks */
547     &uart1_1510,
548     &uart1_16xx,
549     &uart2_ck,
550     &uart3_1510,
551     &uart3_16xx,
552     &usb_clk0,
553     &usb_hhc_ck1510, &usb_hhc_ck16xx,
554     &usb_dc_ck,
555     &mclk_1510,  &mclk_16xx, &mclk_310,
556     &bclk_1510,  &bclk_16xx, &bclk_310,
557     &mmc1_ck,
558     &mmc2_ck,
559     &cam_mclk,
560     &cam_exclk,
561     &cam_lclk,
562     &clk32k,
563     /* Virtual clocks */
564     &i2c_fck,
565     &i2c_ick,
566     0
567 };
568
569 void omap_clk_adduser(struct clk *clk, qemu_irq user)
570 {
571     qemu_irq *i;
572
573     for (i = clk->users; *i; i ++);
574     *i = user;
575 }
576
577 /* If a clock is allowed to idle, it is disabled automatically when
578  * all of clock domains using it are disabled.  */
579 int omap_clk_is_idle(struct clk *clk)
580 {
581     struct clk *chld;
582
583     if (!clk->enabled && (!clk->usecount || !(clk->flags && ALWAYS_ENABLED)))
584         return 1;
585     if (clk->usecount)
586         return 0;
587
588     for (chld = clk->child1; chld; chld = chld->sibling)
589         if (!omap_clk_is_idle(chld))
590             return 0;
591     return 1;
592 }
593
594 struct clk *omap_findclk(struct omap_mpu_state_s *mpu, const char *name)
595 {
596     struct clk *i;
597
598     for (i = mpu->clks; i->name; i ++)
599         if (!strcmp(i->name, name) || (i->alias && !strcmp(i->alias, name)))
600             return i;
601     cpu_abort(mpu->env, "%s: %s not found\n", __FUNCTION__, name);
602 }
603
604 void omap_clk_get(struct clk *clk)
605 {
606     clk->usecount ++;
607 }
608
609 void omap_clk_put(struct clk *clk)
610 {
611     if (!(clk->usecount --))
612         cpu_abort(cpu_single_env, "%s: %s is not in use\n",
613                         __FUNCTION__, clk->name);
614 }
615
616 static void omap_clk_update(struct clk *clk)
617 {
618     int parent, running;
619     qemu_irq *user;
620     struct clk *i;
621
622     if (clk->parent)
623         parent = clk->parent->running;
624     else
625         parent = 1;
626
627     running = parent && (clk->enabled ||
628                     ((clk->flags & ALWAYS_ENABLED) && clk->usecount));
629     if (clk->running != running) {
630         clk->running = running;
631         for (user = clk->users; *user; user ++)
632             qemu_set_irq(*user, running);
633         for (i = clk->child1; i; i = i->sibling)
634             omap_clk_update(i);
635     }
636 }
637
638 static void omap_clk_rate_update_full(struct clk *clk, unsigned long int rate,
639                 unsigned long int div, unsigned long int mult)
640 {
641     struct clk *i;
642     qemu_irq *user;
643
644     clk->rate = muldiv64(rate, mult, div);
645     if (clk->running)
646         for (user = clk->users; *user; user ++)
647             qemu_irq_raise(*user);
648     for (i = clk->child1; i; i = i->sibling)
649         omap_clk_rate_update_full(i, rate,
650                         div * i->divisor, mult * i->multiplier);
651 }
652
653 static void omap_clk_rate_update(struct clk *clk)
654 {
655     struct clk *i;
656     unsigned long int div, mult = div = 1;
657
658     for (i = clk; i->parent; i = i->parent) {
659         div *= i->divisor;
660         mult *= i->multiplier;
661     }
662
663     omap_clk_rate_update_full(clk, i->rate, div, mult);
664 }
665
666 void omap_clk_reparent(struct clk *clk, struct clk *parent)
667 {
668     struct clk **p;
669
670     if (clk->parent) {
671         for (p = &clk->parent->child1; *p != clk; p = &(*p)->sibling);
672         *p = clk->sibling;
673     }
674
675     clk->parent = parent;
676     if (parent) {
677         clk->sibling = parent->child1;
678         parent->child1 = clk;
679         omap_clk_update(clk);
680         omap_clk_rate_update(clk);
681     } else
682         clk->sibling = 0;
683 }
684
685 void omap_clk_onoff(struct clk *clk, int on)
686 {
687     clk->enabled = on;
688     omap_clk_update(clk);
689 }
690
691 void omap_clk_canidle(struct clk *clk, int can)
692 {
693     if (can)
694         omap_clk_put(clk);
695     else
696         omap_clk_get(clk);
697 }
698
699 void omap_clk_setrate(struct clk *clk, int divide, int multiply)
700 {
701     clk->divisor = divide;
702     clk->multiplier = multiply;
703     omap_clk_rate_update(clk);
704 }
705
706 int64_t omap_clk_getrate(omap_clk clk)
707 {
708     return clk->rate;
709 }
710
711 void omap_clk_init(struct omap_mpu_state_s *mpu)
712 {
713     struct clk **i, *j, *k;
714     int count;
715     int flag;
716
717     if (cpu_is_omap310(mpu))
718         flag = CLOCK_IN_OMAP310;
719     else if (cpu_is_omap1510(mpu))
720         flag = CLOCK_IN_OMAP1510;
721     else
722         return;
723
724     for (i = onchip_clks, count = 0; *i; i ++)
725         if ((*i)->flags & flag)
726             count ++;
727     mpu->clks = (struct clk *) qemu_mallocz(sizeof(struct clk) * (count + 1));
728     for (i = onchip_clks, j = mpu->clks; *i; i ++)
729         if ((*i)->flags & flag) {
730             memcpy(j, *i, sizeof(struct clk));
731             for (k = mpu->clks; k < j; k ++)
732                 if (j->parent && !strcmp(j->parent->name, k->name)) {
733                     j->parent = k;
734                     j->sibling = k->child1;
735                     k->child1 = j;
736                 } else if (k->parent && !strcmp(k->parent->name, j->name)) {
737                     k->parent = j;
738                     k->sibling = j->child1;
739                     j->child1 = k;
740                 }
741             j->divisor = j->divisor ?: 1;
742             j->multiplier = j->multiplier ?: 1;
743             j ++;
744         }
745 }