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