Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-pnx4008/clock.c
10817 views
1
/*
2
* arch/arm/mach-pnx4008/clock.c
3
*
4
* Clock control driver for PNX4008
5
*
6
* Authors: Vitaly Wool, Dmitry Chigirev <[email protected]>
7
* Generic clock management functions are partially based on:
8
* linux/arch/arm/mach-omap/clock.c
9
*
10
* 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
11
* the terms of the GNU General Public License version 2. This program
12
* is licensed "as is" without any warranty of any kind, whether express
13
* or implied.
14
*/
15
16
#include <linux/module.h>
17
#include <linux/kernel.h>
18
#include <linux/list.h>
19
#include <linux/errno.h>
20
#include <linux/device.h>
21
#include <linux/err.h>
22
#include <linux/delay.h>
23
#include <linux/io.h>
24
#include <linux/clkdev.h>
25
26
#include <mach/hardware.h>
27
#include <mach/clock.h>
28
#include "clock.h"
29
30
/*forward declaration*/
31
static struct clk per_ck;
32
static struct clk hclk_ck;
33
static struct clk ck_1MHz;
34
static struct clk ck_13MHz;
35
static struct clk ck_pll1;
36
static int local_set_rate(struct clk *clk, u32 rate);
37
38
static inline void clock_lock(void)
39
{
40
local_irq_disable();
41
}
42
43
static inline void clock_unlock(void)
44
{
45
local_irq_enable();
46
}
47
48
static void propagate_rate(struct clk *clk)
49
{
50
struct clk *tmp_clk;
51
52
tmp_clk = clk;
53
while (tmp_clk->propagate_next) {
54
tmp_clk = tmp_clk->propagate_next;
55
local_set_rate(tmp_clk, tmp_clk->user_rate);
56
}
57
}
58
59
static void clk_reg_disable(struct clk *clk)
60
{
61
if (clk->enable_reg)
62
__raw_writel(__raw_readl(clk->enable_reg) &
63
~(1 << clk->enable_shift), clk->enable_reg);
64
}
65
66
static int clk_reg_enable(struct clk *clk)
67
{
68
if (clk->enable_reg)
69
__raw_writel(__raw_readl(clk->enable_reg) |
70
(1 << clk->enable_shift), clk->enable_reg);
71
return 0;
72
}
73
74
static inline void clk_reg_disable1(struct clk *clk)
75
{
76
if (clk->enable_reg1)
77
__raw_writel(__raw_readl(clk->enable_reg1) &
78
~(1 << clk->enable_shift1), clk->enable_reg1);
79
}
80
81
static inline void clk_reg_enable1(struct clk *clk)
82
{
83
if (clk->enable_reg1)
84
__raw_writel(__raw_readl(clk->enable_reg1) |
85
(1 << clk->enable_shift1), clk->enable_reg1);
86
}
87
88
static int clk_wait_for_pll_lock(struct clk *clk)
89
{
90
int i;
91
i = 0;
92
while (i++ < 0xFFF && !(__raw_readl(clk->scale_reg) & 1)) ; /*wait for PLL to lock */
93
94
if (!(__raw_readl(clk->scale_reg) & 1)) {
95
printk(KERN_ERR
96
"%s ERROR: failed to lock, scale reg data: %x\n",
97
clk->name, __raw_readl(clk->scale_reg));
98
return -1;
99
}
100
return 0;
101
}
102
103
static int switch_to_dirty_13mhz(struct clk *clk)
104
{
105
int i;
106
int ret;
107
u32 tmp_reg;
108
109
ret = 0;
110
111
if (!clk->rate)
112
clk_reg_enable1(clk);
113
114
tmp_reg = __raw_readl(clk->parent_switch_reg);
115
/*if 13Mhz clock selected, select 13'MHz (dirty) source from OSC */
116
if (!(tmp_reg & 1)) {
117
tmp_reg |= (1 << 1); /* Trigger switch to 13'MHz (dirty) clock */
118
__raw_writel(tmp_reg, clk->parent_switch_reg);
119
i = 0;
120
while (i++ < 0xFFF && !(__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13'MHz selection status */
121
122
if (!(__raw_readl(clk->parent_switch_reg) & 1)) {
123
printk(KERN_ERR
124
"%s ERROR: failed to select 13'MHz, parent sw reg data: %x\n",
125
clk->name, __raw_readl(clk->parent_switch_reg));
126
ret = -1;
127
}
128
}
129
130
if (!clk->rate)
131
clk_reg_disable1(clk);
132
133
return ret;
134
}
135
136
static int switch_to_clean_13mhz(struct clk *clk)
137
{
138
int i;
139
int ret;
140
u32 tmp_reg;
141
142
ret = 0;
143
144
if (!clk->rate)
145
clk_reg_enable1(clk);
146
147
tmp_reg = __raw_readl(clk->parent_switch_reg);
148
/*if 13'Mhz clock selected, select 13MHz (clean) source from OSC */
149
if (tmp_reg & 1) {
150
tmp_reg &= ~(1 << 1); /* Trigger switch to 13MHz (clean) clock */
151
__raw_writel(tmp_reg, clk->parent_switch_reg);
152
i = 0;
153
while (i++ < 0xFFF && (__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13MHz selection status */
154
155
if (__raw_readl(clk->parent_switch_reg) & 1) {
156
printk(KERN_ERR
157
"%s ERROR: failed to select 13MHz, parent sw reg data: %x\n",
158
clk->name, __raw_readl(clk->parent_switch_reg));
159
ret = -1;
160
}
161
}
162
163
if (!clk->rate)
164
clk_reg_disable1(clk);
165
166
return ret;
167
}
168
169
static int set_13MHz_parent(struct clk *clk, struct clk *parent)
170
{
171
int ret = -EINVAL;
172
173
if (parent == &ck_13MHz)
174
ret = switch_to_clean_13mhz(clk);
175
else if (parent == &ck_pll1)
176
ret = switch_to_dirty_13mhz(clk);
177
178
return ret;
179
}
180
181
#define PLL160_MIN_FCCO 156000
182
#define PLL160_MAX_FCCO 320000
183
184
/*
185
* Calculate pll160 settings.
186
* Possible input: up to 320MHz with step of clk->parent->rate.
187
* In PNX4008 parent rate for pll160s may be either 1 or 13MHz.
188
* Ignored paths: "feedback" (bit 13 set), "div-by-N".
189
* Setting ARM PLL4 rate to 0 will put CPU into direct run mode.
190
* Setting PLL5 and PLL3 rate to 0 will disable USB and DSP clock input.
191
* Please refer to PNX4008 IC manual for details.
192
*/
193
194
static int pll160_set_rate(struct clk *clk, u32 rate)
195
{
196
u32 tmp_reg, tmp_m, tmp_2p, i;
197
u32 parent_rate;
198
int ret = -EINVAL;
199
200
parent_rate = clk->parent->rate;
201
202
if (!parent_rate)
203
goto out;
204
205
/* set direct run for ARM or disable output for others */
206
clk_reg_disable(clk);
207
208
/* disable source input as well (ignored for ARM) */
209
clk_reg_disable1(clk);
210
211
tmp_reg = __raw_readl(clk->scale_reg);
212
tmp_reg &= ~0x1ffff; /*clear all settings, power down */
213
__raw_writel(tmp_reg, clk->scale_reg);
214
215
rate -= rate % parent_rate; /*round down the input */
216
217
if (rate > PLL160_MAX_FCCO)
218
rate = PLL160_MAX_FCCO;
219
220
if (!rate) {
221
clk->rate = 0;
222
ret = 0;
223
goto out;
224
}
225
226
clk_reg_enable1(clk);
227
tmp_reg = __raw_readl(clk->scale_reg);
228
229
if (rate == parent_rate) {
230
/*enter direct bypass mode */
231
tmp_reg |= ((1 << 14) | (1 << 15));
232
__raw_writel(tmp_reg, clk->scale_reg);
233
clk->rate = parent_rate;
234
clk_reg_enable(clk);
235
ret = 0;
236
goto out;
237
}
238
239
i = 0;
240
for (tmp_2p = 1; tmp_2p < 16; tmp_2p <<= 1) {
241
if (rate * tmp_2p >= PLL160_MIN_FCCO)
242
break;
243
i++;
244
}
245
246
if (tmp_2p > 1)
247
tmp_reg |= ((i - 1) << 11);
248
else
249
tmp_reg |= (1 << 14); /*direct mode, no divide */
250
251
tmp_m = rate * tmp_2p;
252
tmp_m /= parent_rate;
253
254
tmp_reg |= (tmp_m - 1) << 1; /*calculate M */
255
tmp_reg |= (1 << 16); /*power up PLL */
256
__raw_writel(tmp_reg, clk->scale_reg);
257
258
if (clk_wait_for_pll_lock(clk) < 0) {
259
clk_reg_disable(clk);
260
clk_reg_disable1(clk);
261
262
tmp_reg = __raw_readl(clk->scale_reg);
263
tmp_reg &= ~0x1ffff; /*clear all settings, power down */
264
__raw_writel(tmp_reg, clk->scale_reg);
265
clk->rate = 0;
266
ret = -EFAULT;
267
goto out;
268
}
269
270
clk->rate = (tmp_m * parent_rate) / tmp_2p;
271
272
if (clk->flags & RATE_PROPAGATES)
273
propagate_rate(clk);
274
275
clk_reg_enable(clk);
276
ret = 0;
277
278
out:
279
return ret;
280
}
281
282
/*configure PER_CLK*/
283
static int per_clk_set_rate(struct clk *clk, u32 rate)
284
{
285
u32 tmp;
286
287
tmp = __raw_readl(clk->scale_reg);
288
tmp &= ~(0x1f << 2);
289
tmp |= ((clk->parent->rate / clk->rate) - 1) << 2;
290
__raw_writel(tmp, clk->scale_reg);
291
clk->rate = rate;
292
return 0;
293
}
294
295
/*configure HCLK*/
296
static int hclk_set_rate(struct clk *clk, u32 rate)
297
{
298
u32 tmp;
299
tmp = __raw_readl(clk->scale_reg);
300
tmp = tmp & ~0x3;
301
switch (rate) {
302
case 1:
303
break;
304
case 2:
305
tmp |= 1;
306
break;
307
case 4:
308
tmp |= 2;
309
break;
310
}
311
312
__raw_writel(tmp, clk->scale_reg);
313
clk->rate = rate;
314
return 0;
315
}
316
317
static u32 hclk_round_rate(struct clk *clk, u32 rate)
318
{
319
switch (rate) {
320
case 1:
321
case 4:
322
return rate;
323
}
324
return 2;
325
}
326
327
static u32 per_clk_round_rate(struct clk *clk, u32 rate)
328
{
329
return CLK_RATE_13MHZ;
330
}
331
332
static int on_off_set_rate(struct clk *clk, u32 rate)
333
{
334
if (rate) {
335
clk_reg_enable(clk);
336
clk->rate = 1;
337
} else {
338
clk_reg_disable(clk);
339
clk->rate = 0;
340
}
341
return 0;
342
}
343
344
static int on_off_inv_set_rate(struct clk *clk, u32 rate)
345
{
346
if (rate) {
347
clk_reg_disable(clk); /*enable bit is inverted */
348
clk->rate = 1;
349
} else {
350
clk_reg_enable(clk);
351
clk->rate = 0;
352
}
353
return 0;
354
}
355
356
static u32 on_off_round_rate(struct clk *clk, u32 rate)
357
{
358
return (rate ? 1 : 0);
359
}
360
361
static u32 pll4_round_rate(struct clk *clk, u32 rate)
362
{
363
if (rate > CLK_RATE_208MHZ)
364
rate = CLK_RATE_208MHZ;
365
if (rate == CLK_RATE_208MHZ && hclk_ck.user_rate == 1)
366
rate = CLK_RATE_208MHZ - CLK_RATE_13MHZ;
367
return (rate - (rate % (hclk_ck.user_rate * CLK_RATE_13MHZ)));
368
}
369
370
static u32 pll3_round_rate(struct clk *clk, u32 rate)
371
{
372
if (rate > CLK_RATE_208MHZ)
373
rate = CLK_RATE_208MHZ;
374
return (rate - rate % CLK_RATE_13MHZ);
375
}
376
377
static u32 pll5_round_rate(struct clk *clk, u32 rate)
378
{
379
return (rate ? CLK_RATE_48MHZ : 0);
380
}
381
382
static u32 ck_13MHz_round_rate(struct clk *clk, u32 rate)
383
{
384
return (rate ? CLK_RATE_13MHZ : 0);
385
}
386
387
static int ck_13MHz_set_rate(struct clk *clk, u32 rate)
388
{
389
if (rate) {
390
clk_reg_disable(clk); /*enable bit is inverted */
391
udelay(500);
392
clk->rate = CLK_RATE_13MHZ;
393
ck_1MHz.rate = CLK_RATE_1MHZ;
394
} else {
395
clk_reg_enable(clk);
396
clk->rate = 0;
397
ck_1MHz.rate = 0;
398
}
399
return 0;
400
}
401
402
static int pll1_set_rate(struct clk *clk, u32 rate)
403
{
404
#if 0 /* doesn't work on some boards, probably a HW BUG */
405
if (rate) {
406
clk_reg_disable(clk); /*enable bit is inverted */
407
if (!clk_wait_for_pll_lock(clk)) {
408
clk->rate = CLK_RATE_13MHZ;
409
} else {
410
clk_reg_enable(clk);
411
clk->rate = 0;
412
}
413
414
} else {
415
clk_reg_enable(clk);
416
clk->rate = 0;
417
}
418
#endif
419
return 0;
420
}
421
422
/* Clock sources */
423
424
static struct clk osc_13MHz = {
425
.name = "osc_13MHz",
426
.flags = FIXED_RATE,
427
.rate = CLK_RATE_13MHZ,
428
};
429
430
static struct clk ck_13MHz = {
431
.name = "ck_13MHz",
432
.parent = &osc_13MHz,
433
.flags = NEEDS_INITIALIZATION,
434
.round_rate = &ck_13MHz_round_rate,
435
.set_rate = &ck_13MHz_set_rate,
436
.enable_reg = OSC13CTRL_REG,
437
.enable_shift = 0,
438
.rate = CLK_RATE_13MHZ,
439
};
440
441
static struct clk osc_32KHz = {
442
.name = "osc_32KHz",
443
.flags = FIXED_RATE,
444
.rate = CLK_RATE_32KHZ,
445
};
446
447
/*attached to PLL5*/
448
static struct clk ck_1MHz = {
449
.name = "ck_1MHz",
450
.flags = FIXED_RATE | PARENT_SET_RATE,
451
.parent = &ck_13MHz,
452
};
453
454
/* PLL1 (397) - provides 13' MHz clock */
455
static struct clk ck_pll1 = {
456
.name = "ck_pll1",
457
.parent = &osc_32KHz,
458
.flags = NEEDS_INITIALIZATION,
459
.round_rate = &ck_13MHz_round_rate,
460
.set_rate = &pll1_set_rate,
461
.enable_reg = PLLCTRL_REG,
462
.enable_shift = 1,
463
.scale_reg = PLLCTRL_REG,
464
.rate = CLK_RATE_13MHZ,
465
};
466
467
/* CPU/Bus PLL */
468
static struct clk ck_pll4 = {
469
.name = "ck_pll4",
470
.parent = &ck_pll1,
471
.flags = RATE_PROPAGATES | NEEDS_INITIALIZATION,
472
.propagate_next = &per_ck,
473
.round_rate = &pll4_round_rate,
474
.set_rate = &pll160_set_rate,
475
.rate = CLK_RATE_208MHZ,
476
.scale_reg = HCLKPLLCTRL_REG,
477
.enable_reg = PWRCTRL_REG,
478
.enable_shift = 2,
479
.parent_switch_reg = SYSCLKCTRL_REG,
480
.set_parent = &set_13MHz_parent,
481
};
482
483
/* USB PLL */
484
static struct clk ck_pll5 = {
485
.name = "ck_pll5",
486
.parent = &ck_1MHz,
487
.flags = NEEDS_INITIALIZATION,
488
.round_rate = &pll5_round_rate,
489
.set_rate = &pll160_set_rate,
490
.scale_reg = USBCTRL_REG,
491
.enable_reg = USBCTRL_REG,
492
.enable_shift = 18,
493
.enable_reg1 = USBCTRL_REG,
494
.enable_shift1 = 17,
495
};
496
497
/* XPERTTeak DSP PLL */
498
static struct clk ck_pll3 = {
499
.name = "ck_pll3",
500
.parent = &ck_pll1,
501
.flags = NEEDS_INITIALIZATION,
502
.round_rate = &pll3_round_rate,
503
.set_rate = &pll160_set_rate,
504
.scale_reg = DSPPLLCTRL_REG,
505
.enable_reg = DSPCLKCTRL_REG,
506
.enable_shift = 3,
507
.enable_reg1 = DSPCLKCTRL_REG,
508
.enable_shift1 = 2,
509
.parent_switch_reg = DSPCLKCTRL_REG,
510
.set_parent = &set_13MHz_parent,
511
};
512
513
static struct clk hclk_ck = {
514
.name = "hclk_ck",
515
.parent = &ck_pll4,
516
.flags = PARENT_SET_RATE,
517
.set_rate = &hclk_set_rate,
518
.round_rate = &hclk_round_rate,
519
.scale_reg = HCLKDIVCTRL_REG,
520
.rate = 2,
521
.user_rate = 2,
522
};
523
524
static struct clk per_ck = {
525
.name = "per_ck",
526
.parent = &ck_pll4,
527
.flags = FIXED_RATE,
528
.propagate_next = &hclk_ck,
529
.set_rate = &per_clk_set_rate,
530
.round_rate = &per_clk_round_rate,
531
.scale_reg = HCLKDIVCTRL_REG,
532
.rate = CLK_RATE_13MHZ,
533
.user_rate = CLK_RATE_13MHZ,
534
};
535
536
static struct clk m2hclk_ck = {
537
.name = "m2hclk_ck",
538
.parent = &hclk_ck,
539
.flags = NEEDS_INITIALIZATION,
540
.round_rate = &on_off_round_rate,
541
.set_rate = &on_off_inv_set_rate,
542
.rate = 1,
543
.enable_shift = 6,
544
.enable_reg = PWRCTRL_REG,
545
};
546
547
static struct clk vfp9_ck = {
548
.name = "vfp9_ck",
549
.parent = &ck_pll4,
550
.flags = NEEDS_INITIALIZATION,
551
.round_rate = &on_off_round_rate,
552
.set_rate = &on_off_set_rate,
553
.rate = 1,
554
.enable_shift = 4,
555
.enable_reg = VFP9CLKCTRL_REG,
556
};
557
558
static struct clk keyscan_ck = {
559
.name = "keyscan_ck",
560
.parent = &osc_32KHz,
561
.flags = NEEDS_INITIALIZATION,
562
.round_rate = &on_off_round_rate,
563
.set_rate = &on_off_set_rate,
564
.enable_shift = 0,
565
.enable_reg = KEYCLKCTRL_REG,
566
};
567
568
static struct clk touch_ck = {
569
.name = "touch_ck",
570
.parent = &osc_32KHz,
571
.flags = NEEDS_INITIALIZATION,
572
.round_rate = &on_off_round_rate,
573
.set_rate = &on_off_set_rate,
574
.enable_shift = 0,
575
.enable_reg = TSCLKCTRL_REG,
576
};
577
578
static struct clk pwm1_ck = {
579
.name = "pwm1_ck",
580
.parent = &osc_32KHz,
581
.flags = NEEDS_INITIALIZATION,
582
.round_rate = &on_off_round_rate,
583
.set_rate = &on_off_set_rate,
584
.enable_shift = 0,
585
.enable_reg = PWMCLKCTRL_REG,
586
};
587
588
static struct clk pwm2_ck = {
589
.name = "pwm2_ck",
590
.parent = &osc_32KHz,
591
.flags = NEEDS_INITIALIZATION,
592
.round_rate = &on_off_round_rate,
593
.set_rate = &on_off_set_rate,
594
.enable_shift = 2,
595
.enable_reg = PWMCLKCTRL_REG,
596
};
597
598
static struct clk jpeg_ck = {
599
.name = "jpeg_ck",
600
.parent = &hclk_ck,
601
.flags = NEEDS_INITIALIZATION,
602
.round_rate = &on_off_round_rate,
603
.set_rate = &on_off_set_rate,
604
.enable_shift = 0,
605
.enable_reg = JPEGCLKCTRL_REG,
606
};
607
608
static struct clk ms_ck = {
609
.name = "ms_ck",
610
.parent = &ck_pll4,
611
.flags = NEEDS_INITIALIZATION,
612
.round_rate = &on_off_round_rate,
613
.set_rate = &on_off_set_rate,
614
.enable_shift = 5,
615
.enable_reg = MSCTRL_REG,
616
};
617
618
static struct clk dum_ck = {
619
.name = "dum_ck",
620
.parent = &hclk_ck,
621
.flags = NEEDS_INITIALIZATION,
622
.round_rate = &on_off_round_rate,
623
.set_rate = &on_off_set_rate,
624
.enable_shift = 0,
625
.enable_reg = DUMCLKCTRL_REG,
626
};
627
628
static struct clk flash_ck = {
629
.name = "flash_ck",
630
.parent = &hclk_ck,
631
.round_rate = &on_off_round_rate,
632
.set_rate = &on_off_set_rate,
633
.enable_shift = 1, /* Only MLC clock supported */
634
.enable_reg = FLASHCLKCTRL_REG,
635
};
636
637
static struct clk i2c0_ck = {
638
.name = "i2c0_ck",
639
.parent = &per_ck,
640
.flags = NEEDS_INITIALIZATION | FIXED_RATE,
641
.enable_shift = 0,
642
.enable_reg = I2CCLKCTRL_REG,
643
.rate = 13000000,
644
.enable = clk_reg_enable,
645
.disable = clk_reg_disable,
646
};
647
648
static struct clk i2c1_ck = {
649
.name = "i2c1_ck",
650
.parent = &per_ck,
651
.flags = NEEDS_INITIALIZATION | FIXED_RATE,
652
.enable_shift = 1,
653
.enable_reg = I2CCLKCTRL_REG,
654
.rate = 13000000,
655
.enable = clk_reg_enable,
656
.disable = clk_reg_disable,
657
};
658
659
static struct clk i2c2_ck = {
660
.name = "i2c2_ck",
661
.parent = &per_ck,
662
.flags = NEEDS_INITIALIZATION | FIXED_RATE,
663
.enable_shift = 2,
664
.enable_reg = USB_OTG_CLKCTRL_REG,
665
.rate = 13000000,
666
.enable = clk_reg_enable,
667
.disable = clk_reg_disable,
668
};
669
670
static struct clk spi0_ck = {
671
.name = "spi0_ck",
672
.parent = &hclk_ck,
673
.flags = NEEDS_INITIALIZATION,
674
.round_rate = &on_off_round_rate,
675
.set_rate = &on_off_set_rate,
676
.enable_shift = 0,
677
.enable_reg = SPICTRL_REG,
678
};
679
680
static struct clk spi1_ck = {
681
.name = "spi1_ck",
682
.parent = &hclk_ck,
683
.flags = NEEDS_INITIALIZATION,
684
.round_rate = &on_off_round_rate,
685
.set_rate = &on_off_set_rate,
686
.enable_shift = 4,
687
.enable_reg = SPICTRL_REG,
688
};
689
690
static struct clk dma_ck = {
691
.name = "dma_ck",
692
.parent = &hclk_ck,
693
.round_rate = &on_off_round_rate,
694
.set_rate = &on_off_set_rate,
695
.enable_shift = 0,
696
.enable_reg = DMACLKCTRL_REG,
697
};
698
699
static struct clk uart3_ck = {
700
.name = "uart3_ck",
701
.parent = &per_ck,
702
.flags = NEEDS_INITIALIZATION,
703
.round_rate = &on_off_round_rate,
704
.set_rate = &on_off_set_rate,
705
.rate = 1,
706
.enable_shift = 0,
707
.enable_reg = UARTCLKCTRL_REG,
708
};
709
710
static struct clk uart4_ck = {
711
.name = "uart4_ck",
712
.parent = &per_ck,
713
.flags = NEEDS_INITIALIZATION,
714
.round_rate = &on_off_round_rate,
715
.set_rate = &on_off_set_rate,
716
.enable_shift = 1,
717
.enable_reg = UARTCLKCTRL_REG,
718
};
719
720
static struct clk uart5_ck = {
721
.name = "uart5_ck",
722
.parent = &per_ck,
723
.flags = NEEDS_INITIALIZATION,
724
.round_rate = &on_off_round_rate,
725
.set_rate = &on_off_set_rate,
726
.rate = 1,
727
.enable_shift = 2,
728
.enable_reg = UARTCLKCTRL_REG,
729
};
730
731
static struct clk uart6_ck = {
732
.name = "uart6_ck",
733
.parent = &per_ck,
734
.flags = NEEDS_INITIALIZATION,
735
.round_rate = &on_off_round_rate,
736
.set_rate = &on_off_set_rate,
737
.enable_shift = 3,
738
.enable_reg = UARTCLKCTRL_REG,
739
};
740
741
static struct clk wdt_ck = {
742
.name = "wdt_ck",
743
.parent = &per_ck,
744
.flags = NEEDS_INITIALIZATION,
745
.enable_shift = 0,
746
.enable_reg = TIMCLKCTRL_REG,
747
.enable = clk_reg_enable,
748
.disable = clk_reg_disable,
749
};
750
751
/* These clocks are visible outside this module
752
* and can be initialized
753
*/
754
static struct clk *onchip_clks[] __initdata = {
755
&ck_13MHz,
756
&ck_pll1,
757
&ck_pll4,
758
&ck_pll5,
759
&ck_pll3,
760
&vfp9_ck,
761
&m2hclk_ck,
762
&hclk_ck,
763
&dma_ck,
764
&flash_ck,
765
&dum_ck,
766
&keyscan_ck,
767
&pwm1_ck,
768
&pwm2_ck,
769
&jpeg_ck,
770
&ms_ck,
771
&touch_ck,
772
&i2c0_ck,
773
&i2c1_ck,
774
&i2c2_ck,
775
&spi0_ck,
776
&spi1_ck,
777
&uart3_ck,
778
&uart4_ck,
779
&uart5_ck,
780
&uart6_ck,
781
&wdt_ck,
782
};
783
784
static struct clk_lookup onchip_clkreg[] = {
785
{ .clk = &ck_13MHz, .con_id = "ck_13MHz" },
786
{ .clk = &ck_pll1, .con_id = "ck_pll1" },
787
{ .clk = &ck_pll4, .con_id = "ck_pll4" },
788
{ .clk = &ck_pll5, .con_id = "ck_pll5" },
789
{ .clk = &ck_pll3, .con_id = "ck_pll3" },
790
{ .clk = &vfp9_ck, .con_id = "vfp9_ck" },
791
{ .clk = &m2hclk_ck, .con_id = "m2hclk_ck" },
792
{ .clk = &hclk_ck, .con_id = "hclk_ck" },
793
{ .clk = &dma_ck, .con_id = "dma_ck" },
794
{ .clk = &flash_ck, .con_id = "flash_ck" },
795
{ .clk = &dum_ck, .con_id = "dum_ck" },
796
{ .clk = &keyscan_ck, .con_id = "keyscan_ck" },
797
{ .clk = &pwm1_ck, .con_id = "pwm1_ck" },
798
{ .clk = &pwm2_ck, .con_id = "pwm2_ck" },
799
{ .clk = &jpeg_ck, .con_id = "jpeg_ck" },
800
{ .clk = &ms_ck, .con_id = "ms_ck" },
801
{ .clk = &touch_ck, .con_id = "touch_ck" },
802
{ .clk = &i2c0_ck, .dev_id = "pnx-i2c.0" },
803
{ .clk = &i2c1_ck, .dev_id = "pnx-i2c.1" },
804
{ .clk = &i2c2_ck, .dev_id = "pnx-i2c.2" },
805
{ .clk = &spi0_ck, .con_id = "spi0_ck" },
806
{ .clk = &spi1_ck, .con_id = "spi1_ck" },
807
{ .clk = &uart3_ck, .con_id = "uart3_ck" },
808
{ .clk = &uart4_ck, .con_id = "uart4_ck" },
809
{ .clk = &uart5_ck, .con_id = "uart5_ck" },
810
{ .clk = &uart6_ck, .con_id = "uart6_ck" },
811
{ .clk = &wdt_ck, .dev_id = "pnx4008-watchdog" },
812
};
813
814
static void local_clk_disable(struct clk *clk)
815
{
816
if (WARN_ON(clk->usecount == 0))
817
return;
818
819
if (!(--clk->usecount)) {
820
if (clk->disable)
821
clk->disable(clk);
822
else if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
823
clk->set_rate(clk, 0);
824
if (clk->parent)
825
local_clk_disable(clk->parent);
826
}
827
}
828
829
static int local_clk_enable(struct clk *clk)
830
{
831
int ret = 0;
832
833
if (clk->usecount == 0) {
834
if (clk->parent) {
835
ret = local_clk_enable(clk->parent);
836
if (ret != 0)
837
goto out;
838
}
839
840
if (clk->enable)
841
ret = clk->enable(clk);
842
else if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
843
&& clk->user_rate)
844
ret = clk->set_rate(clk, clk->user_rate);
845
846
if (ret != 0 && clk->parent) {
847
local_clk_disable(clk->parent);
848
goto out;
849
}
850
851
clk->usecount++;
852
}
853
out:
854
return ret;
855
}
856
857
static int local_set_rate(struct clk *clk, u32 rate)
858
{
859
int ret = -EINVAL;
860
if (clk->set_rate) {
861
862
if (clk->user_rate == clk->rate && clk->parent->rate) {
863
/* if clock enabled or rate not set */
864
clk->user_rate = clk->round_rate(clk, rate);
865
ret = clk->set_rate(clk, clk->user_rate);
866
} else
867
clk->user_rate = clk->round_rate(clk, rate);
868
ret = 0;
869
}
870
return ret;
871
}
872
873
int clk_set_rate(struct clk *clk, unsigned long rate)
874
{
875
int ret = -EINVAL;
876
877
if (clk->flags & FIXED_RATE)
878
goto out;
879
880
clock_lock();
881
if ((clk->flags & PARENT_SET_RATE) && clk->parent) {
882
883
clk->user_rate = clk->round_rate(clk, rate);
884
/* parent clock needs to be refreshed
885
for the setting to take effect */
886
} else {
887
ret = local_set_rate(clk, rate);
888
}
889
ret = 0;
890
clock_unlock();
891
892
out:
893
return ret;
894
}
895
896
EXPORT_SYMBOL(clk_set_rate);
897
898
unsigned long clk_get_rate(struct clk *clk)
899
{
900
unsigned long ret;
901
clock_lock();
902
ret = clk->rate;
903
clock_unlock();
904
return ret;
905
}
906
EXPORT_SYMBOL(clk_get_rate);
907
908
int clk_enable(struct clk *clk)
909
{
910
int ret;
911
912
clock_lock();
913
ret = local_clk_enable(clk);
914
clock_unlock();
915
return ret;
916
}
917
918
EXPORT_SYMBOL(clk_enable);
919
920
void clk_disable(struct clk *clk)
921
{
922
clock_lock();
923
local_clk_disable(clk);
924
clock_unlock();
925
}
926
927
EXPORT_SYMBOL(clk_disable);
928
929
long clk_round_rate(struct clk *clk, unsigned long rate)
930
{
931
long ret;
932
clock_lock();
933
if (clk->round_rate)
934
ret = clk->round_rate(clk, rate);
935
else
936
ret = clk->rate;
937
clock_unlock();
938
return ret;
939
}
940
941
EXPORT_SYMBOL(clk_round_rate);
942
943
int clk_set_parent(struct clk *clk, struct clk *parent)
944
{
945
int ret = -ENODEV;
946
if (!clk->set_parent)
947
goto out;
948
949
clock_lock();
950
ret = clk->set_parent(clk, parent);
951
if (!ret)
952
clk->parent = parent;
953
clock_unlock();
954
955
out:
956
return ret;
957
}
958
959
EXPORT_SYMBOL(clk_set_parent);
960
961
static int __init clk_init(void)
962
{
963
struct clk **clkp;
964
965
/* Disable autoclocking, as it doesn't seem to work */
966
__raw_writel(0xff, AUTOCLK_CTRL);
967
968
for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
969
clkp++) {
970
struct clk *clk = *clkp;
971
if (clk->flags & NEEDS_INITIALIZATION) {
972
if (clk->set_rate) {
973
clk->user_rate = clk->rate;
974
local_set_rate(clk, clk->user_rate);
975
if (clk->set_parent)
976
clk->set_parent(clk, clk->parent);
977
}
978
if (clk->enable && clk->usecount)
979
clk->enable(clk);
980
if (clk->disable && !clk->usecount)
981
clk->disable(clk);
982
}
983
pr_debug("%s: clock %s, rate %ld\n",
984
__func__, clk->name, clk->rate);
985
}
986
987
local_clk_enable(&ck_pll4);
988
989
/* if ck_13MHz is not used, disable it. */
990
if (ck_13MHz.usecount == 0)
991
local_clk_disable(&ck_13MHz);
992
993
/* Disable autoclocking */
994
__raw_writeb(0xff, AUTOCLK_CTRL);
995
996
clkdev_add_table(onchip_clkreg, ARRAY_SIZE(onchip_clkreg));
997
998
return 0;
999
}
1000
1001
arch_initcall(clk_init);
1002
1003