Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/powerpc/platforms/512x/clock.c
10820 views
1
/*
2
* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved.
3
*
4
* Author: John Rigby <[email protected]>
5
*
6
* Implements the clk api defined in include/linux/clk.h
7
*
8
* Original based on linux/arch/arm/mach-integrator/clock.c
9
*
10
* Copyright (C) 2004 ARM Limited.
11
* Written by Deep Blue Solutions Limited.
12
*
13
* This program is free software; you can redistribute it and/or modify
14
* it under the terms of the GNU General Public License version 2 as
15
* published by the Free Software Foundation.
16
*/
17
#include <linux/kernel.h>
18
#include <linux/list.h>
19
#include <linux/errno.h>
20
#include <linux/err.h>
21
#include <linux/string.h>
22
#include <linux/clk.h>
23
#include <linux/mutex.h>
24
#include <linux/io.h>
25
26
#include <linux/of_platform.h>
27
#include <asm/mpc5xxx.h>
28
#include <asm/clk_interface.h>
29
30
#undef CLK_DEBUG
31
32
static int clocks_initialized;
33
34
#define CLK_HAS_RATE 0x1 /* has rate in MHz */
35
#define CLK_HAS_CTRL 0x2 /* has control reg and bit */
36
37
struct clk {
38
struct list_head node;
39
char name[32];
40
int flags;
41
struct device *dev;
42
unsigned long rate;
43
struct module *owner;
44
void (*calc) (struct clk *);
45
struct clk *parent;
46
int reg, bit; /* CLK_HAS_CTRL */
47
int div_shift; /* only used by generic_div_clk_calc */
48
};
49
50
static LIST_HEAD(clocks);
51
static DEFINE_MUTEX(clocks_mutex);
52
53
static struct clk *mpc5121_clk_get(struct device *dev, const char *id)
54
{
55
struct clk *p, *clk = ERR_PTR(-ENOENT);
56
int dev_match = 0;
57
int id_match = 0;
58
59
if (dev == NULL || id == NULL)
60
return clk;
61
62
mutex_lock(&clocks_mutex);
63
list_for_each_entry(p, &clocks, node) {
64
if (dev == p->dev)
65
dev_match++;
66
if (strcmp(id, p->name) == 0)
67
id_match++;
68
if ((dev_match || id_match) && try_module_get(p->owner)) {
69
clk = p;
70
break;
71
}
72
}
73
mutex_unlock(&clocks_mutex);
74
75
return clk;
76
}
77
78
#ifdef CLK_DEBUG
79
static void dump_clocks(void)
80
{
81
struct clk *p;
82
83
mutex_lock(&clocks_mutex);
84
printk(KERN_INFO "CLOCKS:\n");
85
list_for_each_entry(p, &clocks, node) {
86
pr_info(" %s=%ld", p->name, p->rate);
87
if (p->parent)
88
pr_cont(" %s=%ld", p->parent->name,
89
p->parent->rate);
90
if (p->flags & CLK_HAS_CTRL)
91
pr_cont(" reg/bit=%d/%d", p->reg, p->bit);
92
pr_cont("\n");
93
}
94
mutex_unlock(&clocks_mutex);
95
}
96
#define DEBUG_CLK_DUMP() dump_clocks()
97
#else
98
#define DEBUG_CLK_DUMP()
99
#endif
100
101
102
static void mpc5121_clk_put(struct clk *clk)
103
{
104
module_put(clk->owner);
105
}
106
107
#define NRPSC 12
108
109
struct mpc512x_clockctl {
110
u32 spmr; /* System PLL Mode Reg */
111
u32 sccr[2]; /* System Clk Ctrl Reg 1 & 2 */
112
u32 scfr1; /* System Clk Freq Reg 1 */
113
u32 scfr2; /* System Clk Freq Reg 2 */
114
u32 reserved;
115
u32 bcr; /* Bread Crumb Reg */
116
u32 pccr[NRPSC]; /* PSC Clk Ctrl Reg 0-11 */
117
u32 spccr; /* SPDIF Clk Ctrl Reg */
118
u32 cccr; /* CFM Clk Ctrl Reg */
119
u32 dccr; /* DIU Clk Cnfg Reg */
120
};
121
122
struct mpc512x_clockctl __iomem *clockctl;
123
124
static int mpc5121_clk_enable(struct clk *clk)
125
{
126
unsigned int mask;
127
128
if (clk->flags & CLK_HAS_CTRL) {
129
mask = in_be32(&clockctl->sccr[clk->reg]);
130
mask |= 1 << clk->bit;
131
out_be32(&clockctl->sccr[clk->reg], mask);
132
}
133
return 0;
134
}
135
136
static void mpc5121_clk_disable(struct clk *clk)
137
{
138
unsigned int mask;
139
140
if (clk->flags & CLK_HAS_CTRL) {
141
mask = in_be32(&clockctl->sccr[clk->reg]);
142
mask &= ~(1 << clk->bit);
143
out_be32(&clockctl->sccr[clk->reg], mask);
144
}
145
}
146
147
static unsigned long mpc5121_clk_get_rate(struct clk *clk)
148
{
149
if (clk->flags & CLK_HAS_RATE)
150
return clk->rate;
151
else
152
return 0;
153
}
154
155
static long mpc5121_clk_round_rate(struct clk *clk, unsigned long rate)
156
{
157
return rate;
158
}
159
160
static int mpc5121_clk_set_rate(struct clk *clk, unsigned long rate)
161
{
162
return 0;
163
}
164
165
static int clk_register(struct clk *clk)
166
{
167
mutex_lock(&clocks_mutex);
168
list_add(&clk->node, &clocks);
169
mutex_unlock(&clocks_mutex);
170
return 0;
171
}
172
173
static unsigned long spmf_mult(void)
174
{
175
/*
176
* Convert spmf to multiplier
177
*/
178
static int spmf_to_mult[] = {
179
68, 1, 12, 16,
180
20, 24, 28, 32,
181
36, 40, 44, 48,
182
52, 56, 60, 64
183
};
184
int spmf = (clockctl->spmr >> 24) & 0xf;
185
return spmf_to_mult[spmf];
186
}
187
188
static unsigned long sysdiv_div_x_2(void)
189
{
190
/*
191
* Convert sysdiv to divisor x 2
192
* Some divisors have fractional parts so
193
* multiply by 2 then divide by this value
194
*/
195
static int sysdiv_to_div_x_2[] = {
196
4, 5, 6, 7,
197
8, 9, 10, 14,
198
12, 16, 18, 22,
199
20, 24, 26, 30,
200
28, 32, 34, 38,
201
36, 40, 42, 46,
202
44, 48, 50, 54,
203
52, 56, 58, 62,
204
60, 64, 66,
205
};
206
int sysdiv = (clockctl->scfr2 >> 26) & 0x3f;
207
return sysdiv_to_div_x_2[sysdiv];
208
}
209
210
static unsigned long ref_to_sys(unsigned long rate)
211
{
212
rate *= spmf_mult();
213
rate *= 2;
214
rate /= sysdiv_div_x_2();
215
216
return rate;
217
}
218
219
static unsigned long sys_to_ref(unsigned long rate)
220
{
221
rate *= sysdiv_div_x_2();
222
rate /= 2;
223
rate /= spmf_mult();
224
225
return rate;
226
}
227
228
static long ips_to_ref(unsigned long rate)
229
{
230
int ips_div = (clockctl->scfr1 >> 23) & 0x7;
231
232
rate *= ips_div; /* csb_clk = ips_clk * ips_div */
233
rate *= 2; /* sys_clk = csb_clk * 2 */
234
return sys_to_ref(rate);
235
}
236
237
static unsigned long devtree_getfreq(char *clockname)
238
{
239
struct device_node *np;
240
const unsigned int *prop;
241
unsigned int val = 0;
242
243
np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr");
244
if (np) {
245
prop = of_get_property(np, clockname, NULL);
246
if (prop)
247
val = *prop;
248
of_node_put(np);
249
}
250
return val;
251
}
252
253
static void ref_clk_calc(struct clk *clk)
254
{
255
unsigned long rate;
256
257
rate = devtree_getfreq("bus-frequency");
258
if (rate == 0) {
259
printk(KERN_ERR "No bus-frequency in dev tree\n");
260
clk->rate = 0;
261
return;
262
}
263
clk->rate = ips_to_ref(rate);
264
}
265
266
static struct clk ref_clk = {
267
.name = "ref_clk",
268
.calc = ref_clk_calc,
269
};
270
271
272
static void sys_clk_calc(struct clk *clk)
273
{
274
clk->rate = ref_to_sys(ref_clk.rate);
275
}
276
277
static struct clk sys_clk = {
278
.name = "sys_clk",
279
.calc = sys_clk_calc,
280
};
281
282
static void diu_clk_calc(struct clk *clk)
283
{
284
int diudiv_x_2 = clockctl->scfr1 & 0xff;
285
unsigned long rate;
286
287
rate = sys_clk.rate;
288
289
rate *= 2;
290
rate /= diudiv_x_2;
291
292
clk->rate = rate;
293
}
294
295
static void viu_clk_calc(struct clk *clk)
296
{
297
unsigned long rate;
298
299
rate = sys_clk.rate;
300
rate /= 2;
301
clk->rate = rate;
302
}
303
304
static void half_clk_calc(struct clk *clk)
305
{
306
clk->rate = clk->parent->rate / 2;
307
}
308
309
static void generic_div_clk_calc(struct clk *clk)
310
{
311
int div = (clockctl->scfr1 >> clk->div_shift) & 0x7;
312
313
clk->rate = clk->parent->rate / div;
314
}
315
316
static void unity_clk_calc(struct clk *clk)
317
{
318
clk->rate = clk->parent->rate;
319
}
320
321
static struct clk csb_clk = {
322
.name = "csb_clk",
323
.calc = half_clk_calc,
324
.parent = &sys_clk,
325
};
326
327
static void e300_clk_calc(struct clk *clk)
328
{
329
int spmf = (clockctl->spmr >> 16) & 0xf;
330
int ratex2 = clk->parent->rate * spmf;
331
332
clk->rate = ratex2 / 2;
333
}
334
335
static struct clk e300_clk = {
336
.name = "e300_clk",
337
.calc = e300_clk_calc,
338
.parent = &csb_clk,
339
};
340
341
static struct clk ips_clk = {
342
.name = "ips_clk",
343
.calc = generic_div_clk_calc,
344
.parent = &csb_clk,
345
.div_shift = 23,
346
};
347
348
/*
349
* Clocks controlled by SCCR1 (.reg = 0)
350
*/
351
static struct clk lpc_clk = {
352
.name = "lpc_clk",
353
.flags = CLK_HAS_CTRL,
354
.reg = 0,
355
.bit = 30,
356
.calc = generic_div_clk_calc,
357
.parent = &ips_clk,
358
.div_shift = 11,
359
};
360
361
static struct clk nfc_clk = {
362
.name = "nfc_clk",
363
.flags = CLK_HAS_CTRL,
364
.reg = 0,
365
.bit = 29,
366
.calc = generic_div_clk_calc,
367
.parent = &ips_clk,
368
.div_shift = 8,
369
};
370
371
static struct clk pata_clk = {
372
.name = "pata_clk",
373
.flags = CLK_HAS_CTRL,
374
.reg = 0,
375
.bit = 28,
376
.calc = unity_clk_calc,
377
.parent = &ips_clk,
378
};
379
380
/*
381
* PSC clocks (bits 27 - 16)
382
* are setup elsewhere
383
*/
384
385
static struct clk sata_clk = {
386
.name = "sata_clk",
387
.flags = CLK_HAS_CTRL,
388
.reg = 0,
389
.bit = 14,
390
.calc = unity_clk_calc,
391
.parent = &ips_clk,
392
};
393
394
static struct clk fec_clk = {
395
.name = "fec_clk",
396
.flags = CLK_HAS_CTRL,
397
.reg = 0,
398
.bit = 13,
399
.calc = unity_clk_calc,
400
.parent = &ips_clk,
401
};
402
403
static struct clk pci_clk = {
404
.name = "pci_clk",
405
.flags = CLK_HAS_CTRL,
406
.reg = 0,
407
.bit = 11,
408
.calc = generic_div_clk_calc,
409
.parent = &csb_clk,
410
.div_shift = 20,
411
};
412
413
/*
414
* Clocks controlled by SCCR2 (.reg = 1)
415
*/
416
static struct clk diu_clk = {
417
.name = "diu_clk",
418
.flags = CLK_HAS_CTRL,
419
.reg = 1,
420
.bit = 31,
421
.calc = diu_clk_calc,
422
};
423
424
static struct clk viu_clk = {
425
.name = "viu_clk",
426
.flags = CLK_HAS_CTRL,
427
.reg = 1,
428
.bit = 18,
429
.calc = viu_clk_calc,
430
};
431
432
static struct clk axe_clk = {
433
.name = "axe_clk",
434
.flags = CLK_HAS_CTRL,
435
.reg = 1,
436
.bit = 30,
437
.calc = unity_clk_calc,
438
.parent = &csb_clk,
439
};
440
441
static struct clk usb1_clk = {
442
.name = "usb1_clk",
443
.flags = CLK_HAS_CTRL,
444
.reg = 1,
445
.bit = 28,
446
.calc = unity_clk_calc,
447
.parent = &csb_clk,
448
};
449
450
static struct clk usb2_clk = {
451
.name = "usb2_clk",
452
.flags = CLK_HAS_CTRL,
453
.reg = 1,
454
.bit = 27,
455
.calc = unity_clk_calc,
456
.parent = &csb_clk,
457
};
458
459
static struct clk i2c_clk = {
460
.name = "i2c_clk",
461
.flags = CLK_HAS_CTRL,
462
.reg = 1,
463
.bit = 26,
464
.calc = unity_clk_calc,
465
.parent = &ips_clk,
466
};
467
468
static struct clk mscan_clk = {
469
.name = "mscan_clk",
470
.flags = CLK_HAS_CTRL,
471
.reg = 1,
472
.bit = 25,
473
.calc = unity_clk_calc,
474
.parent = &ips_clk,
475
};
476
477
static struct clk sdhc_clk = {
478
.name = "sdhc_clk",
479
.flags = CLK_HAS_CTRL,
480
.reg = 1,
481
.bit = 24,
482
.calc = unity_clk_calc,
483
.parent = &ips_clk,
484
};
485
486
static struct clk mbx_bus_clk = {
487
.name = "mbx_bus_clk",
488
.flags = CLK_HAS_CTRL,
489
.reg = 1,
490
.bit = 22,
491
.calc = half_clk_calc,
492
.parent = &csb_clk,
493
};
494
495
static struct clk mbx_clk = {
496
.name = "mbx_clk",
497
.flags = CLK_HAS_CTRL,
498
.reg = 1,
499
.bit = 21,
500
.calc = unity_clk_calc,
501
.parent = &csb_clk,
502
};
503
504
static struct clk mbx_3d_clk = {
505
.name = "mbx_3d_clk",
506
.flags = CLK_HAS_CTRL,
507
.reg = 1,
508
.bit = 20,
509
.calc = generic_div_clk_calc,
510
.parent = &mbx_bus_clk,
511
.div_shift = 14,
512
};
513
514
static void psc_mclk_in_calc(struct clk *clk)
515
{
516
clk->rate = devtree_getfreq("psc_mclk_in");
517
if (!clk->rate)
518
clk->rate = 25000000;
519
}
520
521
static struct clk psc_mclk_in = {
522
.name = "psc_mclk_in",
523
.calc = psc_mclk_in_calc,
524
};
525
526
static struct clk spdif_txclk = {
527
.name = "spdif_txclk",
528
.flags = CLK_HAS_CTRL,
529
.reg = 1,
530
.bit = 23,
531
};
532
533
static struct clk spdif_rxclk = {
534
.name = "spdif_rxclk",
535
.flags = CLK_HAS_CTRL,
536
.reg = 1,
537
.bit = 23,
538
};
539
540
static void ac97_clk_calc(struct clk *clk)
541
{
542
/* ac97 bit clock is always 24.567 MHz */
543
clk->rate = 24567000;
544
}
545
546
static struct clk ac97_clk = {
547
.name = "ac97_clk_in",
548
.calc = ac97_clk_calc,
549
};
550
551
struct clk *rate_clks[] = {
552
&ref_clk,
553
&sys_clk,
554
&diu_clk,
555
&viu_clk,
556
&csb_clk,
557
&e300_clk,
558
&ips_clk,
559
&fec_clk,
560
&sata_clk,
561
&pata_clk,
562
&nfc_clk,
563
&lpc_clk,
564
&mbx_bus_clk,
565
&mbx_clk,
566
&mbx_3d_clk,
567
&axe_clk,
568
&usb1_clk,
569
&usb2_clk,
570
&i2c_clk,
571
&mscan_clk,
572
&sdhc_clk,
573
&pci_clk,
574
&psc_mclk_in,
575
&spdif_txclk,
576
&spdif_rxclk,
577
&ac97_clk,
578
NULL
579
};
580
581
static void rate_clk_init(struct clk *clk)
582
{
583
if (clk->calc) {
584
clk->calc(clk);
585
clk->flags |= CLK_HAS_RATE;
586
clk_register(clk);
587
} else {
588
printk(KERN_WARNING
589
"Could not initialize clk %s without a calc routine\n",
590
clk->name);
591
}
592
}
593
594
static void rate_clks_init(void)
595
{
596
struct clk **cpp, *clk;
597
598
cpp = rate_clks;
599
while ((clk = *cpp++))
600
rate_clk_init(clk);
601
}
602
603
/*
604
* There are two clk enable registers with 32 enable bits each
605
* psc clocks and device clocks are all stored in dev_clks
606
*/
607
struct clk dev_clks[2][32];
608
609
/*
610
* Given a psc number return the dev_clk
611
* associated with it
612
*/
613
static struct clk *psc_dev_clk(int pscnum)
614
{
615
int reg, bit;
616
struct clk *clk;
617
618
reg = 0;
619
bit = 27 - pscnum;
620
621
clk = &dev_clks[reg][bit];
622
clk->reg = 0;
623
clk->bit = bit;
624
return clk;
625
}
626
627
/*
628
* PSC clock rate calculation
629
*/
630
static void psc_calc_rate(struct clk *clk, int pscnum, struct device_node *np)
631
{
632
unsigned long mclk_src = sys_clk.rate;
633
unsigned long mclk_div;
634
635
/*
636
* Can only change value of mclk divider
637
* when the divider is disabled.
638
*
639
* Zero is not a valid divider so minimum
640
* divider is 1
641
*
642
* disable/set divider/enable
643
*/
644
out_be32(&clockctl->pccr[pscnum], 0);
645
out_be32(&clockctl->pccr[pscnum], 0x00020000);
646
out_be32(&clockctl->pccr[pscnum], 0x00030000);
647
648
if (clockctl->pccr[pscnum] & 0x80) {
649
clk->rate = spdif_rxclk.rate;
650
return;
651
}
652
653
switch ((clockctl->pccr[pscnum] >> 14) & 0x3) {
654
case 0:
655
mclk_src = sys_clk.rate;
656
break;
657
case 1:
658
mclk_src = ref_clk.rate;
659
break;
660
case 2:
661
mclk_src = psc_mclk_in.rate;
662
break;
663
case 3:
664
mclk_src = spdif_txclk.rate;
665
break;
666
}
667
668
mclk_div = ((clockctl->pccr[pscnum] >> 17) & 0x7fff) + 1;
669
clk->rate = mclk_src / mclk_div;
670
}
671
672
/*
673
* Find all psc nodes in device tree and assign a clock
674
* with name "psc%d_mclk" and dev pointing at the device
675
* returned from of_find_device_by_node
676
*/
677
static void psc_clks_init(void)
678
{
679
struct device_node *np;
680
const u32 *cell_index;
681
struct platform_device *ofdev;
682
683
for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") {
684
cell_index = of_get_property(np, "cell-index", NULL);
685
if (cell_index) {
686
int pscnum = *cell_index;
687
struct clk *clk = psc_dev_clk(pscnum);
688
689
clk->flags = CLK_HAS_RATE | CLK_HAS_CTRL;
690
ofdev = of_find_device_by_node(np);
691
clk->dev = &ofdev->dev;
692
/*
693
* AC97 is special rate clock does
694
* not go through normal path
695
*/
696
if (strcmp("ac97", np->name) == 0)
697
clk->rate = ac97_clk.rate;
698
else
699
psc_calc_rate(clk, pscnum, np);
700
sprintf(clk->name, "psc%d_mclk", pscnum);
701
clk_register(clk);
702
clk_enable(clk);
703
}
704
}
705
}
706
707
static struct clk_interface mpc5121_clk_functions = {
708
.clk_get = mpc5121_clk_get,
709
.clk_enable = mpc5121_clk_enable,
710
.clk_disable = mpc5121_clk_disable,
711
.clk_get_rate = mpc5121_clk_get_rate,
712
.clk_put = mpc5121_clk_put,
713
.clk_round_rate = mpc5121_clk_round_rate,
714
.clk_set_rate = mpc5121_clk_set_rate,
715
.clk_set_parent = NULL,
716
.clk_get_parent = NULL,
717
};
718
719
int __init mpc5121_clk_init(void)
720
{
721
struct device_node *np;
722
723
np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock");
724
if (np) {
725
clockctl = of_iomap(np, 0);
726
of_node_put(np);
727
}
728
729
if (!clockctl) {
730
printk(KERN_ERR "Could not map clock control registers\n");
731
return 0;
732
}
733
734
rate_clks_init();
735
psc_clks_init();
736
737
/* leave clockctl mapped forever */
738
/*iounmap(clockctl); */
739
DEBUG_CLK_DUMP();
740
clocks_initialized++;
741
clk_functions = mpc5121_clk_functions;
742
return 0;
743
}
744
745