Statistics
| Branch: | Revision:

root / hw / omap_clk.c @ b4e3104b

History | View | Annotate | Download (18.7 kB)

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 "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;                /* Is currently ticking */
41
    int enabled;                /* Is enabled, regardless of its input clk */
42
    unsigned long rate;                /* Current rate (if .running) */
43
    unsigned int divisor;        /* Rate relative to input (if .enabled) */
44
    unsigned int multiplier;        /* Rate relative to input (if .enabled) */
45
    qemu_irq users[16];                /* Who to notify on change */
46
    int usecount;                /* Automatically idle when unused */
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
/* If a dpll is disabled it becomes a bypass, child clocks don't stop */
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,        /* either dpll4 or apll */
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,        /* either dpll1 or ck_ref */
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,        /* either CLKIN or DPLL1 */
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
    /* Note: On 16xx the frequency can be divided by 2 by programming
197
     * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
198
     *
199
     * 1510 version is in TC clocks.
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
    /* Note: On 1510 the frequency follows TC_CK
247
     *
248
     * 16xx version is in MPU clocks.
249
     */
250
};
251

    
252
static struct clk tipb_ck = {
253
    /* No-idle controlled by "tc_ck" */
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
    /* No-idle controlled by "tc_ck" */
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
    /* No-idle controlled by "tc_ck" */
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
    /* Direct from ULPD, no real parent */
344
    .parent        = &armper_ck,        /* either armper_ck or dpll4 */
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
    /* Direct from ULPD, no real parent */
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
    /* Direct from ULPD, no real parent */
360
    .parent        = &armper_ck,        /* either armper_ck or dpll4 */
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
    /* Direct from ULPD, no real parent */
369
    .parent        = &armper_ck,        /* either armper_ck or dpll4 */
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
    /* Direct from ULPD, no real parent */
377
    .parent        = &armper_ck,
378
    .rate        = 48000000,
379
    .flags        = CLOCK_IN_OMAP16XX,
380
};
381

    
382
static struct clk usb_clk0 = {        /* 6 MHz output on W4_USB_CLK0 */
383
    .name        = "usb_clk0",
384
    .alias        = "usb.clko",
385
    /* Direct from ULPD, no parent */
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
    /* Direct from ULPD, no parent */
393
    .rate        = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
394
    .flags        = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
395
};
396

    
397
static struct clk usb_hhc_ck16xx = {
398
    .name        = "usb_hhc_ck",
399
    /* Direct from ULPD, no parent */
400
    .rate        = 48000000,
401
    /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
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
    /* Direct from ULPD, no parent. May be enabled by ext hardware. */
416
    .rate        = 12000000,
417
    .flags        = CLOCK_IN_OMAP1510,
418
};
419

    
420
static struct clk bclk_310 = {
421
    .name        = "bt_mclk_out",        /* Alias midi_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
    /* Direct from ULPD, no parent. May be enabled by ext hardware. */
435
    .flags        = CLOCK_IN_OMAP16XX,
436
};
437

    
438
static struct clk bclk_1510 = {
439
    .name        = "bclk",
440
    /* Direct from ULPD, no parent. May be enabled by ext hardware. */
441
    .rate        = 12000000,
442
    .flags        = CLOCK_IN_OMAP1510,
443
};
444

    
445
static struct clk bclk_16xx = {
446
    .name        = "bclk",
447
    /* Direct from ULPD, no parent. May be enabled by ext hardware. */
448
    .flags        = CLOCK_IN_OMAP16XX,
449
};
450

    
451
static struct clk mmc1_ck = {
452
    .name        = "mmc_ck",
453
    .id                = 1,
454
    /* Functional clock is direct from ULPD, interface clock is ARMPER */
455
    .parent        = &armper_ck,        /* either armper_ck or dpll4 */
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
    /* Functional clock is direct from ULPD, interface clock is ARMPER */
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
    /* Either 12M from cam.mclk or 48M from dpll4 */
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
    /* non-ULPD clocks */
511
    &xtal_osc12m,
512
    &xtal_osc32k,
513
    &ck_ref,
514
    &dpll1,
515
    &dpll2,
516
    &dpll3,
517
    &dpll4,
518
    &apll,
519
    &ck_48m,
520
    /* CK_GEN1 clocks */
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
    /* CK_GEN2 clocks */
532
    &clkm2,
533
    &dsp_ck,
534
    &dspmmu_ck,
535
    &dspper_ck,
536
    &dspxor_ck,
537
    &dsptim_ck,
538
    /* CK_GEN3 clocks */
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
    /* ULPD clocks */
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
    /* Virtual clocks */
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
/* If a clock is allowed to idle, it is disabled automatically when
587
 * all of clock domains using it are disabled.  */
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)
619
{
620
    if (!(clk->usecount --))
621
        cpu_abort(cpu_single_env, "%s: %s is not in use\n",
622
                        __FUNCTION__, clk->name);
623
}
624

    
625
static void omap_clk_update(struct clk *clk)
626
{
627
    int parent, running;
628
    qemu_irq *user;
629
    struct clk *i;
630

    
631
    if (clk->parent)
632
        parent = clk->parent->running;
633
    else
634
        parent = 1;
635

    
636
    running = parent && (clk->enabled ||
637
                    ((clk->flags & ALWAYS_ENABLED) && clk->usecount));
638
    if (clk->running != running) {
639
        clk->running = running;
640
        for (user = clk->users; *user; user ++)
641
            qemu_set_irq(*user, running);
642
        for (i = clk->child1; i; i = i->sibling)
643
            omap_clk_update(i);
644
    }
645
}
646

    
647
static void omap_clk_rate_update_full(struct clk *clk, unsigned long int rate,
648
                unsigned long int div, unsigned long int mult)
649
{
650
    struct clk *i;
651
    qemu_irq *user;
652

    
653
    clk->rate = muldiv64(rate, mult, div);
654
    if (clk->running)
655
        for (user = clk->users; *user; user ++)
656
            qemu_irq_raise(*user);
657
    for (i = clk->child1; i; i = i->sibling)
658
        omap_clk_rate_update_full(i, rate,
659
                        div * i->divisor, mult * i->multiplier);
660
}
661

    
662
static void omap_clk_rate_update(struct clk *clk)
663
{
664
    struct clk *i;
665
    unsigned long int div, mult = div = 1;
666

    
667
    for (i = clk; i->parent; i = i->parent) {
668
        div *= i->divisor;
669
        mult *= i->multiplier;
670
    }
671

    
672
    omap_clk_rate_update_full(clk, i->rate, div, mult);
673
}
674

    
675
void omap_clk_reparent(struct clk *clk, struct clk *parent)
676
{
677
    struct clk **p;
678

    
679
    if (clk->parent) {
680
        for (p = &clk->parent->child1; *p != clk; p = &(*p)->sibling);
681
        *p = clk->sibling;
682
    }
683

    
684
    clk->parent = parent;
685
    if (parent) {
686
        clk->sibling = parent->child1;
687
        parent->child1 = clk;
688
        omap_clk_update(clk);
689
        omap_clk_rate_update(clk);
690
    } else
691
        clk->sibling = 0;
692
}
693

    
694
void omap_clk_onoff(struct clk *clk, int on)
695
{
696
    clk->enabled = on;
697
    omap_clk_update(clk);
698
}
699

    
700
void omap_clk_canidle(struct clk *clk, int can)
701
{
702
    if (can)
703
        omap_clk_put(clk);
704
    else
705
        omap_clk_get(clk);
706
}
707

    
708
void omap_clk_setrate(struct clk *clk, int divide, int multiply)
709
{
710
    clk->divisor = divide;
711
    clk->multiplier = multiply;
712
    omap_clk_rate_update(clk);
713
}
714

    
715
int64_t omap_clk_getrate(omap_clk clk)
716
{
717
    return clk->rate;
718
}
719

    
720
void omap_clk_init(struct omap_mpu_state_s *mpu)
721
{
722
    struct clk **i, *j, *k;
723
    int count;
724
    int flag;
725

    
726
    if (cpu_is_omap310(mpu))
727
        flag = CLOCK_IN_OMAP310;
728
    else if (cpu_is_omap1510(mpu))
729
        flag = CLOCK_IN_OMAP1510;
730
    else
731
        return;
732

    
733
    for (i = onchip_clks, count = 0; *i; i ++)
734
        if ((*i)->flags & flag)
735
            count ++;
736
    mpu->clks = (struct clk *) qemu_mallocz(sizeof(struct clk) * (count + 1));
737
    for (i = onchip_clks, j = mpu->clks; *i; i ++)
738
        if ((*i)->flags & flag) {
739
            memcpy(j, *i, sizeof(struct clk));
740
            for (k = mpu->clks; k < j; k ++)
741
                if (j->parent && !strcmp(j->parent->name, k->name)) {
742
                    j->parent = k;
743
                    j->sibling = k->child1;
744
                    k->child1 = j;
745
                } else if (k->parent && !strcmp(k->parent->name, j->name)) {
746
                    k->parent = j;
747
                    k->sibling = j->child1;
748
                    j->child1 = k;
749
                }
750
            j->divisor = j->divisor ?: 1;
751
            j->multiplier = j->multiplier ?: 1;
752
            j ++;
753
        }
754
    for (j = mpu->clks; count --; j ++) {
755
        omap_clk_update(j);
756
        omap_clk_rate_update(j);
757
    }
758
}