xref: /openbmc/qemu/hw/misc/omap_clk.c (revision 062cfce8d4c077800d252b84c65da8a2dd03fd6f)
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