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