• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/powerpc/platforms/512x/
1/*
2 * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: John Rigby <jrigby@freescale.com>
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
32static 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
37struct 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
50static LIST_HEAD(clocks);
51static DEFINE_MUTEX(clocks_mutex);
52
53static 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
79static 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
102static void mpc5121_clk_put(struct clk *clk)
103{
104	module_put(clk->owner);
105}
106
107#define NRPSC 12
108
109struct 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
122struct mpc512x_clockctl __iomem *clockctl;
123
124static 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
136static 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
147static 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
155static long mpc5121_clk_round_rate(struct clk *clk, unsigned long rate)
156{
157	return rate;
158}
159
160static int mpc5121_clk_set_rate(struct clk *clk, unsigned long rate)
161{
162	return 0;
163}
164
165static 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
173static 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
188static 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
210static 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
219static 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
228static 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
237static 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
253static 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
266static struct clk ref_clk = {
267	.name = "ref_clk",
268	.calc = ref_clk_calc,
269};
270
271
272static void sys_clk_calc(struct clk *clk)
273{
274	clk->rate = ref_to_sys(ref_clk.rate);
275}
276
277static struct clk sys_clk = {
278	.name = "sys_clk",
279	.calc = sys_clk_calc,
280};
281
282static 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
295static 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
304static void half_clk_calc(struct clk *clk)
305{
306	clk->rate = clk->parent->rate / 2;
307}
308
309static 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
316static void unity_clk_calc(struct clk *clk)
317{
318	clk->rate = clk->parent->rate;
319}
320
321static struct clk csb_clk = {
322	.name = "csb_clk",
323	.calc = half_clk_calc,
324	.parent = &sys_clk,
325};
326
327static 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
335static struct clk e300_clk = {
336	.name = "e300_clk",
337	.calc = e300_clk_calc,
338	.parent = &csb_clk,
339};
340
341static 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 */
351static 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
361static 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
371static 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
385static 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
394static 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
403static 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 */
416static 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
424static 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
432static 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
441static 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
450static 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
459static 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
468static 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
477static 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
486static 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
495static 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
504static 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
514static 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
521static struct clk psc_mclk_in = {
522	.name = "psc_mclk_in",
523	.calc = psc_mclk_in_calc,
524};
525
526static struct clk spdif_txclk = {
527	.name = "spdif_txclk",
528	.flags = CLK_HAS_CTRL,
529	.reg = 1,
530	.bit = 23,
531};
532
533static struct clk spdif_rxclk = {
534	.name = "spdif_rxclk",
535	.flags = CLK_HAS_CTRL,
536	.reg = 1,
537	.bit = 23,
538};
539
540static void ac97_clk_calc(struct clk *clk)
541{
542	/* ac97 bit clock is always 24.567 MHz */
543	clk->rate = 24567000;
544}
545
546static struct clk ac97_clk = {
547	.name = "ac97_clk_in",
548	.calc = ac97_clk_calc,
549};
550
551struct 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
581static 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
594static 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 */
607struct clk dev_clks[2][32];
608
609/*
610 * Given a psc number return the dev_clk
611 * associated with it
612 */
613static 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 */
630static 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 */
677static 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
707static 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
719int __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