1 /* arch/arm/mach-rk29/clock.c
3 * Copyright (C) 2010 ROCKCHIP, Inc.
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
17 #define pr_fmt(fmt) "clock: %s: " fmt, __func__
19 #include <linux/clk.h>
20 #include <linux/debugfs.h>
21 #include <linux/delay.h>
22 #include <linux/err.h>
23 #include <linux/init.h>
24 #include <linux/interrupt.h>
26 #include <linux/kernel.h>
27 #include <linux/list.h>
28 #include <linux/module.h>
29 #include <linux/version.h>
30 #include <asm/clkdev.h>
31 #include <mach/rk29_iomap.h>
35 #define PLL_BAND (0x01 << 16)
36 #define PLL_PD (0x01 << 15)
38 #define PLL_CLKR(i) ((((i) - 1) << & 0x1f) << 10)
39 #define PLL_NR(v) ((((v) >> 10) & 0x1f) + 1)
41 #define PLL_CLKF(i) ((((i) - 1) & 0x7f) << 3)
42 #define PLL_NF(v) ((((v) >> 3) & 0x7f) + 1)
43 #define PLL_NF2(v) (((((v) >> 3) & 0x7f) + 1) << 1)
45 #define PLL_CLKOD(i) (((i) & 0x03) << 1)
46 #define PLL_NO_1 PLL_CLKOD(0)
47 #define PLL_NO_2 PLL_CLKOD(1)
48 #define PLL_NO_4 PLL_CLKOD(2)
49 #define PLL_NO_8 PLL_CLKOD(3)
50 #define PLL_NO_SHIFT(v) (((v) >> 1) & 0x03)
52 #define PLL_BYPASS (0x01)
55 #define CRU_CPU_MODE_MASK (0x03u << 0)
56 #define CRU_CPU_MODE_SLOW (0x00u << 0)
57 #define CRU_CPU_MODE_NORMAL (0x01u << 0)
58 #define CRU_CPU_MODE_DSLOW (0x02u << 0)
60 #define CRU_PERIPH_MODE_MASK (0x03u << 2)
61 #define CRU_PERIPH_MODE_SLOW (0x00u << 2)
62 #define CRU_PERIPH_MODE_NORMAL (0x01u << 2)
63 #define CRU_PERIPH_MODE_DSLOW (0x02u << 2)
65 #define CRU_CODEC_MODE_MASK (0x03u << 4)
66 #define CRU_CODEC_MODE_SLOW (0x00u << 4)
67 #define CRU_CODEC_MODE_NORMAL (0x01u << 4)
68 #define CRU_CODEC_MODE_DSLOW (0x02u << 4)
70 #define CRU_DDR_MODE_MASK (0x03u << 6)
71 #define CRU_DDR_MODE_SLOW (0x00u << 6)
72 #define CRU_DDR_MODE_NORMAL (0x01u << 6)
73 #define CRU_DDR_MODE_DSLOW (0x02u << 6)
77 #define RATE_FIXED (1 << 1) /* Fixed clock rate */
78 #define CONFIG_PARTICIPANT (1 << 10) /* Fundamental clock */
79 #define ENABLE_ON_INIT (1 << 11) /* Enable upon framework init */
81 #define cru_readl(offset) readl(RK29_CRU_BASE + offset)
82 #define cru_writel(v, offset) writel(v, RK29_CRU_BASE + offset)
83 #define cru_writel_force(v, offset) do { u32 _v = v; u32 _count = 5; do { cru_writel(_v, offset); } while (cru_readl(offset) != _v && _count--); } while (0) /* huangtao: when write CRU_xPLL_CON, first time may failed, so try again. unknown why. */
86 struct list_head node;
89 struct list_head children;
90 struct list_head sibling; /* node for children */
93 int (*mode)(struct clk *clk, int on);
94 unsigned long (*recalc)(struct clk *); /* if null, follow parent */
95 int (*set_rate)(struct clk *, unsigned long);
96 long (*round_rate)(struct clk *, unsigned long);
97 struct clk* (*get_parent)(struct clk *); /* get clk's parent from the hardware. default is clksel_get_parent if parents present */
98 int (*set_parent)(struct clk *, struct clk *); /* default is clksel_set_parent if parents present */
106 u8 clksel_parent_mask;
107 u8 clksel_parent_shift;
108 struct clk **parents;
111 int ddr_disabled = 0;
113 static void __clk_disable(struct clk *clk);
114 static void __clk_reparent(struct clk *child, struct clk *parent);
115 static void __propagate_rate(struct clk *tclk);
117 static unsigned long clksel_recalc_div(struct clk *clk)
119 u32 div = ((cru_readl(clk->clksel_con) >> clk->clksel_shift) & clk->clksel_mask) + 1;
120 unsigned long rate = clk->parent->rate / div;
121 pr_debug("%s new clock rate is %lu (div %u)\n", clk->name, rate, div);
125 static unsigned long clksel_recalc_shift(struct clk *clk)
127 u32 shift = (cru_readl(clk->clksel_con) >> clk->clksel_shift) & clk->clksel_mask;
128 unsigned long rate = clk->parent->rate >> shift;
129 pr_debug("%s new clock rate is %lu (shift %u)\n", clk->name, rate, shift);
133 static unsigned long clksel_recalc_frac(struct clk *clk)
137 u32 r = cru_readl(clk->clksel_con), numerator, denominator;
138 if (r == 0) // FPGA ?
139 return clk->parent->rate;
141 denominator = r & 0xFFFF;
142 rate64 = (u64)clk->parent->rate * numerator;
143 do_div(rate64, denominator);
145 pr_debug("%s new clock rate is %lu (frac %u/%u)\n", clk->name, rate, numerator, denominator);
149 static int clksel_set_rate_div(struct clk *clk, unsigned long rate)
153 for (div = 0; div <= clk->clksel_mask; div++) {
154 u32 new_rate = clk->parent->rate / (div + 1);
155 if (new_rate <= rate) {
156 u32 v = cru_readl(clk->clksel_con);
157 v &= ~((u32) clk->clksel_mask << clk->clksel_shift);
158 v |= div << clk->clksel_shift;
159 cru_writel(v, clk->clksel_con);
160 clk->rate = new_rate;
161 pr_debug("clksel_set_rate_div for clock %s to rate %ld (div %d)\n", clk->name, rate, div + 1);
169 static int clksel_set_rate_shift(struct clk *clk, unsigned long rate)
173 for (shift = 0; (1 << shift) <= clk->clksel_maxdiv; shift++) {
174 u32 new_rate = clk->parent->rate >> shift;
175 if (new_rate <= rate) {
176 u32 v = cru_readl(clk->clksel_con);
177 v &= ~((u32) clk->clksel_mask << clk->clksel_shift);
178 v |= shift << clk->clksel_shift;
179 cru_writel(v, clk->clksel_con);
180 clk->rate = new_rate;
181 pr_debug("clksel_set_rate_shift for clock %s to rate %ld (shift %d)\n", clk->name, rate, shift);
189 static struct clk* clksel_get_parent(struct clk *clk)
191 return clk->parents[(cru_readl(clk->clksel_con) >> clk->clksel_parent_shift) & clk->clksel_parent_mask];
194 static int clksel_set_parent(struct clk *clk, struct clk *parent)
196 struct clk **p = clk->parents;
201 for (i = 0; (i <= clk->clksel_parent_mask) && *p; i++, p++) {
205 v = cru_readl(clk->clksel_con);
206 v &= ~((u32) clk->clksel_parent_mask << clk->clksel_parent_shift);
207 v |= (i << clk->clksel_parent_shift);
208 cru_writel(v, clk->clksel_con);
214 static int gate_mode(struct clk *clk, int on)
217 int idx = clk->gate_idx;
220 if (idx >= CLK_GATE_MAX)
223 reg = CRU_CLKGATE0_CON;
224 reg += (idx >> 5) << 2;
229 v &= ~(1 << idx); // clear bit
231 v |= (1 << idx); // set bit
238 static struct clk xin24m = {
244 static struct clk clk_12m = {
251 static struct clk extclk = {
257 static struct clk otgphy0_clkin = {
258 .name = "otgphy0_clkin",
263 static struct clk otgphy1_clkin = {
264 .name = "otgphy1_clkin",
270 static unsigned long arm_pll_clk_recalc(struct clk *clk)
274 if ((cru_readl(CRU_MODE_CON) & CRU_CPU_MODE_MASK) == CRU_CPU_MODE_NORMAL) {
275 u32 v = cru_readl(CRU_APLL_CON);
276 u64 rate64 = (u64) clk->parent->rate * PLL_NF2(v);
277 do_div(rate64, PLL_NR(v));
278 rate = rate64 >> PLL_NO_SHIFT(v);
279 pr_debug("%s new clock rate is %ld (NF %d NR %d NO %d)\n", clk->name, rate, PLL_NF2(v), PLL_NR(v), 1 << PLL_NO_SHIFT(v));
281 rate = clk->parent->rate;
282 pr_debug("%s new clock rate is %ld (slow mode)\n", clk->name, rate);
288 static struct clk arm_pll_clk = {
291 .recalc = arm_pll_clk_recalc,
294 static unsigned long ddr_pll_clk_recalc(struct clk *clk)
298 if ((cru_readl(CRU_MODE_CON) & CRU_DDR_MODE_MASK) == CRU_DDR_MODE_NORMAL) {
299 u32 v = cru_readl(CRU_DPLL_CON);
300 u64 rate64 = (u64) clk->parent->rate * PLL_NF(v);
301 do_div(rate64, PLL_NR(v));
302 rate = rate64 >> PLL_NO_SHIFT(v);
303 pr_debug("%s new clock rate is %ld (NF %d NR %d NO %d)\n", clk->name, rate, PLL_NF(v), PLL_NR(v), 1 << PLL_NO_SHIFT(v));
305 rate = clk->parent->rate;
306 pr_debug("%s new clock rate is %ld (slow mode)\n", clk->name, rate);
312 static struct clk ddr_pll_clk = {
315 .recalc = ddr_pll_clk_recalc,
319 static unsigned long codec_pll_clk_recalc(struct clk *clk)
323 if ((cru_readl(CRU_MODE_CON) & CRU_CODEC_MODE_MASK) == CRU_CODEC_MODE_NORMAL) {
324 u32 v = cru_readl(CRU_CPLL_CON);
325 u64 rate64 = (u64) clk->parent->rate * PLL_NF(v);
326 do_div(rate64, PLL_NR(v));
327 rate = rate64 >> PLL_NO_SHIFT(v);
328 pr_debug("%s new clock rate is %ld (NF %d NR %d NO %d)\n", clk->name, rate, PLL_NF(v), PLL_NR(v), 1 << PLL_NO_SHIFT(v));
330 rate = clk->parent->rate;
331 pr_debug("%s new clock rate is %ld (slow mode)\n", clk->name, rate);
337 static struct clk codec_pll_clk = {
340 .recalc = codec_pll_clk_recalc,
344 static unsigned long periph_pll_clk_recalc(struct clk *clk)
348 if ((cru_readl(CRU_MODE_CON) & CRU_CODEC_MODE_MASK) == CRU_CODEC_MODE_NORMAL) {
349 u32 v = cru_readl(CRU_CPLL_CON);
350 u64 rate64 = (u64) clk->parent->rate * PLL_NF(v);
351 do_div(rate64, PLL_NR(v));
352 rate = rate64 >> PLL_NO_SHIFT(v);
353 pr_debug("%s new clock rate is %ld (NF %d NR %d NO %d)\n", clk->name, rate, PLL_NF(v), PLL_NR(v), 1 << PLL_NO_SHIFT(v));
355 rate = clk->parent->rate;
356 pr_debug("%s new clock rate is %ld (slow mode)\n", clk->name, rate);
362 static struct clk periph_pll_clk = {
363 .name = "periph_pll",
365 .recalc = periph_pll_clk_recalc,
369 static struct clk clk_core = {
371 .parent = &arm_pll_clk,
372 .recalc = clksel_recalc_div,
373 .clksel_con = CRU_CLKSEL0_CON,
378 static unsigned long aclk_cpu_recalc(struct clk *clk)
381 u32 div = ((cru_readl(CRU_CLKSEL0_CON) >> 5) & 0x7) + 1;
386 rate = clk->parent->rate / div;
387 pr_debug("%s new clock rate is %ld (div %d)\n", clk->name, rate, div);
392 static struct clk aclk_cpu = {
395 .recalc = aclk_cpu_recalc,
398 static struct clk hclk_cpu = {
401 .recalc = clksel_recalc_shift,
402 .clksel_con = CRU_CLKSEL0_CON,
408 static struct clk pclk_cpu = {
411 .recalc = clksel_recalc_shift,
412 .clksel_con = CRU_CLKSEL0_CON,
418 static struct clk aclk_periph = {
419 .name = "aclk_periph",
420 .parent = &periph_pll_clk,
421 .recalc = clksel_recalc_div,
422 .clksel_con = CRU_CLKSEL0_CON,
427 static struct clk pclk_periph = {
428 .name = "pclk_periph",
429 .parent = &aclk_periph,
430 .recalc = clksel_recalc_shift,
431 .clksel_con = CRU_CLKSEL0_CON,
437 static struct clk hclk_periph = {
438 .name = "hclk_periph",
439 .parent = &aclk_periph,
440 .recalc = clksel_recalc_shift,
441 .clksel_con = CRU_CLKSEL0_CON,
448 static struct clk *clk_uhost_parents[8] = { &periph_pll_clk, &ddr_pll_clk, &codec_pll_clk, &arm_pll_clk, &otgphy0_clkin, &otgphy1_clkin };
450 static struct clk clk_uhost = {
453 .recalc = clksel_recalc_div,
454 .set_rate = clksel_set_rate_div,
455 .gate_idx = CLK_GATE_UHOST,
456 .clksel_con = CRU_CLKSEL1_CON,
459 .clksel_parent_mask = 7,
460 .clksel_parent_shift = 13,
461 .parents = clk_uhost_parents,
464 static struct clk *clk_otgphy_parents[4] = { &xin24m, &clk_12m, &clk_uhost };
466 static struct clk clk_otgphy0 = {
468 .clksel_con = CRU_CLKSEL1_CON,
469 .clksel_parent_mask = 3,
470 .clksel_parent_shift = 9,
471 .parents = clk_otgphy_parents,
474 static struct clk clk_otgphy1 = {
476 .clksel_con = CRU_CLKSEL1_CON,
477 .clksel_parent_mask = 3,
478 .clksel_parent_shift = 11,
479 .parents = clk_otgphy_parents,
483 static struct clk rmii_clkin = {
484 .name = "rmii_clkin",
487 static struct clk *clk_mac_ref_div_parents[4] = { &arm_pll_clk, &periph_pll_clk, &codec_pll_clk, &ddr_pll_clk };
489 static struct clk clk_mac_ref_div = {
490 .name = "mac_ref_div",
491 .recalc = clksel_recalc_div,
492 .set_rate = clksel_set_rate_div,
493 .clksel_con = CRU_CLKSEL1_CON,
496 .clksel_parent_mask = 3,
497 .clksel_parent_shift = 21,
498 .parents = clk_mac_ref_div_parents,
501 static struct clk *clk_mac_ref_parents[2] = { &clk_mac_ref_div, &rmii_clkin };
503 static struct clk clk_mac_ref = {
505 .clksel_con = CRU_CLKSEL1_CON,
506 .clksel_parent_mask = 1,
507 .clksel_parent_shift = 28,
508 .parents = clk_mac_ref_parents,
512 static struct clk *clk_i2s_div_parents[8] = { &codec_pll_clk, &periph_pll_clk, &arm_pll_clk, &ddr_pll_clk, &otgphy0_clkin, &otgphy1_clkin };
514 static struct clk clk_i2s0_div = {
516 .recalc = clksel_recalc_div,
517 .set_rate = clksel_set_rate_div,
518 .clksel_con = CRU_CLKSEL2_CON,
521 .clksel_parent_mask = 7,
522 .clksel_parent_shift = 0,
523 .parents = clk_i2s_div_parents,
526 static struct clk clk_i2s1_div = {
528 .recalc = clksel_recalc_div,
529 .set_rate = clksel_set_rate_div,
530 .clksel_con = CRU_CLKSEL2_CON,
533 .clksel_parent_mask = 7,
534 .clksel_parent_shift = 10,
535 .parents = clk_i2s_div_parents,
538 static struct clk clk_spdif_div = {
540 .recalc = clksel_recalc_div,
541 .set_rate = clksel_set_rate_div,
542 .clksel_con = CRU_CLKSEL2_CON,
545 .clksel_parent_mask = 7,
546 .clksel_parent_shift = 20,
547 .parents = clk_i2s_div_parents,
550 static struct clk clk_i2s0_frac_div = {
551 .name = "i2s0_frac_div",
552 .parent = &clk_i2s0_div,
553 .recalc = clksel_recalc_frac,
554 .clksel_con = CRU_CLKSEL3_CON,
557 static struct clk clk_i2s1_frac_div = {
558 .name = "i2s1_frac_div",
559 .parent = &clk_i2s1_div,
560 .recalc = clksel_recalc_frac,
561 .clksel_con = CRU_CLKSEL4_CON,
564 static struct clk clk_spdif_frac_div = {
565 .name = "spdif_frac_div",
566 .parent = &clk_spdif_div,
567 .recalc = clksel_recalc_frac,
568 .clksel_con = CRU_CLKSEL5_CON,
571 static struct clk *clk_i2s0_parents[4] = { &clk_i2s0_div, &clk_i2s0_frac_div, &clk_12m, &xin24m };
573 static struct clk clk_i2s0 = {
575 .clksel_con = CRU_CLKSEL2_CON,
576 .clksel_parent_mask = 3,
577 .clksel_parent_shift = 8,
578 .parents = clk_i2s0_parents,
581 static struct clk *clk_i2s1_parents[4] = { &clk_i2s1_div, &clk_i2s1_frac_div, &clk_12m, &xin24m };
583 static struct clk clk_i2s1 = {
585 .clksel_con = CRU_CLKSEL2_CON,
586 .clksel_parent_mask = 3,
587 .clksel_parent_shift = 18,
588 .parents = clk_i2s1_parents,
591 static struct clk *clk_spdif_parents[4] = { &clk_spdif_div, &clk_spdif_frac_div, &clk_12m, &xin24m };
593 static struct clk clk_spdif = {
595 .clksel_con = CRU_CLKSEL2_CON,
596 .clksel_parent_mask = 3,
597 .clksel_parent_shift = 28,
598 .parents = clk_spdif_parents,
602 static struct clk *clk_spi_src_parents[4] = { &periph_pll_clk, &ddr_pll_clk, &codec_pll_clk, &arm_pll_clk };
604 static struct clk clk_spi_src = {
606 .clksel_con = CRU_CLKSEL6_CON,
607 .clksel_parent_mask = 3,
608 .clksel_parent_shift = 0,
609 .parents = clk_spi_src_parents,
612 static struct clk clk_spi0 = {
614 .parent = &clk_spi_src,
616 .recalc = clksel_recalc_div,
617 .set_rate = clksel_set_rate_div,
618 .gate_idx = CLK_GATE_SPI0,
619 .clksel_con = CRU_CLKSEL6_CON,
624 static struct clk clk_spi1 = {
626 .parent = &clk_spi_src,
628 .recalc = clksel_recalc_div,
629 .set_rate = clksel_set_rate_div,
630 .gate_idx = CLK_GATE_SPI1,
631 .clksel_con = CRU_CLKSEL6_CON,
637 static struct clk clk_saradc = {
639 .parent = &pclk_periph,
641 .recalc = clksel_recalc_div,
642 .set_rate = clksel_set_rate_div,
643 .gate_idx = CLK_GATE_SARADC,
644 .clksel_con = CRU_CLKSEL6_CON,
650 static struct clk *clk_cpu_timer_parents[2] = { &pclk_cpu, &xin24m };
652 static struct clk clk_timer0 = {
655 .gate_idx = CLK_GATE_TIMER0,
656 .clksel_con = CRU_CLKSEL6_CON,
657 .clksel_parent_mask = 1,
658 .clksel_parent_shift = 26,
659 .parents = clk_cpu_timer_parents,
662 static struct clk clk_timer1 = {
665 .gate_idx = CLK_GATE_TIMER1,
666 .clksel_con = CRU_CLKSEL6_CON,
667 .clksel_parent_mask = 1,
668 .clksel_parent_shift = 27,
669 .parents = clk_cpu_timer_parents,
672 static struct clk *clk_periph_timer_parents[2] = { &pclk_periph, &xin24m };
674 static struct clk clk_timer2 = {
677 .gate_idx = CLK_GATE_TIMER2,
678 .clksel_con = CRU_CLKSEL6_CON,
679 .clksel_parent_mask = 1,
680 .clksel_parent_shift = 28,
681 .parents = clk_periph_timer_parents,
684 static struct clk clk_timer3 = {
687 .gate_idx = CLK_GATE_TIMER3,
688 .clksel_con = CRU_CLKSEL6_CON,
689 .clksel_parent_mask = 1,
690 .clksel_parent_shift = 29,
691 .parents = clk_periph_timer_parents,
695 static struct clk *clk_sdmmc_src_parents[4] = { &arm_pll_clk, &periph_pll_clk, &codec_pll_clk, &ddr_pll_clk };
697 static struct clk clk_sdmmc_src = {
699 .clksel_con = CRU_CLKSEL7_CON,
700 .clksel_parent_mask = 3,
701 .clksel_parent_shift = 0,
702 .parents = clk_sdmmc_src_parents,
705 static struct clk clk_sdmmc0 = {
707 .parent = &clk_sdmmc_src,
709 .recalc = clksel_recalc_div,
710 .set_rate = clksel_set_rate_div,
711 .gate_idx = CLK_GATE_SDMMC0,
712 .clksel_con = CRU_CLKSEL7_CON,
717 static struct clk clk_sdmmc1 = {
719 .parent = &clk_sdmmc_src,
721 .recalc = clksel_recalc_div,
722 .set_rate = clksel_set_rate_div,
723 .gate_idx = CLK_GATE_SDMMC1,
724 .clksel_con = CRU_CLKSEL7_CON,
729 static struct clk clk_emmc = {
731 .parent = &clk_sdmmc_src,
733 .recalc = clksel_recalc_div,
734 .set_rate = clksel_set_rate_div,
735 .gate_idx = CLK_GATE_EMMC,
736 .clksel_con = CRU_CLKSEL7_CON,
742 static struct clk *clk_ddr_parents[8] = { &ddr_pll_clk, &periph_pll_clk, &codec_pll_clk, &arm_pll_clk };
744 static struct clk clk_ddr = {
746 .recalc = clksel_recalc_shift,
747 .clksel_con = CRU_CLKSEL7_CON,
751 .clksel_parent_mask = 3,
752 .clksel_parent_shift = 24,
753 .parents = clk_ddr_parents,
757 static struct clk *clk_uart_src_parents[8] = { &periph_pll_clk, &ddr_pll_clk, &codec_pll_clk, &arm_pll_clk, &otgphy0_clkin, &otgphy1_clkin };
759 static struct clk clk_uart01_src = {
760 .name = "uart01_src",
761 .clksel_con = CRU_CLKSEL8_CON,
762 .clksel_parent_mask = 7,
763 .clksel_parent_shift = 0,
764 .parents = clk_uart_src_parents,
767 static struct clk clk_uart0_div = {
769 .parent = &clk_uart01_src,
770 .recalc = clksel_recalc_div,
771 .set_rate = clksel_set_rate_div,
772 .clksel_con = CRU_CLKSEL8_CON,
777 static struct clk clk_uart0_frac_div = {
778 .name = "uart0_frac_div",
779 .parent = &clk_uart0_div,
780 .recalc = clksel_recalc_frac,
781 .clksel_con = CRU_CLKSEL10_CON,
784 static struct clk *clk_uart0_parents[4] = { &clk_uart0_div, &clk_uart0_frac_div, &xin24m };
786 static struct clk clk_uart0 = {
789 .gate_idx = CLK_GATE_UART0,
790 .clksel_con = CRU_CLKSEL8_CON,
791 .clksel_parent_mask = 3,
792 .clksel_parent_shift = 9,
793 .parents = clk_uart0_parents,
796 static struct clk clk_uart1_div = {
798 .parent = &clk_uart01_src,
799 .recalc = clksel_recalc_div,
800 .set_rate = clksel_set_rate_div,
801 .clksel_con = CRU_CLKSEL8_CON,
806 static struct clk clk_uart1_frac_div = {
807 .name = "uart1_frac_div",
808 .parent = &clk_uart1_div,
809 .recalc = clksel_recalc_frac,
810 .clksel_con = CRU_CLKSEL11_CON,
813 static struct clk *clk_uart1_parents[4] = { &clk_uart1_div, &clk_uart1_frac_div, &xin24m };
815 static struct clk clk_uart1 = {
818 .gate_idx = CLK_GATE_UART1,
819 .clksel_con = CRU_CLKSEL8_CON,
820 .clksel_parent_mask = 3,
821 .clksel_parent_shift = 20,
822 .parents = clk_uart1_parents,
825 static struct clk clk_uart23_src = {
826 .name = "uart23_src",
827 .clksel_con = CRU_CLKSEL9_CON,
828 .clksel_parent_mask = 7,
829 .clksel_parent_shift = 0,
830 .parents = clk_uart_src_parents,
833 static struct clk clk_uart2_div = {
835 .parent = &clk_uart23_src,
836 .recalc = clksel_recalc_div,
837 .set_rate = clksel_set_rate_div,
838 .clksel_con = CRU_CLKSEL9_CON,
843 static struct clk clk_uart2_frac_div = {
844 .name = "uart2_frac_div",
845 .parent = &clk_uart2_div,
846 .recalc = clksel_recalc_frac,
847 .clksel_con = CRU_CLKSEL12_CON,
850 static struct clk *clk_uart2_parents[4] = { &clk_uart2_div, &clk_uart2_frac_div, &xin24m };
852 static struct clk clk_uart2 = {
855 .gate_idx = CLK_GATE_UART2,
856 .clksel_con = CRU_CLKSEL9_CON,
857 .clksel_parent_mask = 3,
858 .clksel_parent_shift = 9,
859 .parents = clk_uart2_parents,
862 static struct clk clk_uart3_div = {
864 .parent = &clk_uart23_src,
865 .recalc = clksel_recalc_div,
866 .set_rate = clksel_set_rate_div,
867 .clksel_con = CRU_CLKSEL9_CON,
872 static struct clk clk_uart3_frac_div = {
873 .name = "uart3_frac_div",
874 .parent = &clk_uart3_div,
875 .recalc = clksel_recalc_frac,
876 .clksel_con = CRU_CLKSEL13_CON,
879 static struct clk *clk_uart3_parents[4] = { &clk_uart3_div, &clk_uart3_frac_div, &xin24m };
881 static struct clk clk_uart3 = {
884 .gate_idx = CLK_GATE_UART3,
885 .clksel_con = CRU_CLKSEL9_CON,
886 .clksel_parent_mask = 3,
887 .clksel_parent_shift = 20,
888 .parents = clk_uart3_parents,
892 static struct clk *clk_hsadc_div_parents[8] = { &codec_pll_clk, &ddr_pll_clk, &periph_pll_clk, &arm_pll_clk, &otgphy0_clkin, &otgphy1_clkin };
894 static struct clk clk_hsadc_div = {
896 .recalc = clksel_recalc_div,
897 .set_rate = clksel_set_rate_div,
898 .clksel_con = CRU_CLKSEL14_CON,
901 .clksel_parent_mask = 7,
902 .clksel_parent_shift = 7,
903 .parents = clk_hsadc_div_parents,
906 static struct clk clk_hsadc_frac_div = {
907 .name = "hsadc_frac_div",
908 .parent = &clk_hsadc_div,
909 .recalc = clksel_recalc_frac,
910 .clksel_con = CRU_CLKSEL15_CON,
913 static struct clk *clk_demod_parents[4] = { &clk_hsadc_div, &clk_hsadc_frac_div, &extclk };
915 static struct clk clk_demod = {
917 .clksel_con = CRU_CLKSEL14_CON,
918 .clksel_parent_mask = 3,
919 .clksel_parent_shift = 18,
920 .parents = clk_demod_parents,
923 static struct clk gpsclk = {
927 static struct clk *clk_hsadc_parents[2] = { &clk_demod, &gpsclk };
929 static struct clk clk_hsadc = {
931 .clksel_con = CRU_CLKSEL14_CON,
932 .clksel_parent_mask = 1,
933 .clksel_parent_shift = 21,
934 .parents = clk_hsadc_parents,
937 static unsigned long div2_recalc(struct clk *clk)
939 return clk->parent->rate >> 1;
942 static struct clk clk_hsadc_div2 = {
943 .name = "hsadc_div2",
944 .parent = &clk_demod,
945 .recalc = div2_recalc,
948 static struct clk clk_hsadc_div2_inv = {
949 .name = "hsadc_div2_inv",
950 .parent = &clk_demod,
951 .recalc = div2_recalc,
954 static struct clk *clk_hsadc_out_parents[2] = { &clk_hsadc_div2, &clk_hsadc_div2_inv };
956 static struct clk clk_hsadc_out = {
958 .clksel_con = CRU_CLKSEL14_CON,
959 .clksel_parent_mask = 1,
960 .clksel_parent_shift = 20,
961 .parents = clk_hsadc_out_parents,
965 static struct clk *dclk_lcdc_div_parents[4] = { &codec_pll_clk, &ddr_pll_clk, &periph_pll_clk, &arm_pll_clk };
967 static struct clk dclk_lcdc_div = {
968 .name = "dclk_lcdc_div",
969 .recalc = clksel_recalc_div,
970 .set_rate = clksel_set_rate_div,
971 .clksel_con = CRU_CLKSEL16_CON,
974 .clksel_parent_mask = 3,
975 .clksel_parent_shift = 0,
976 .parents = dclk_lcdc_div_parents,
979 static struct clk *dclk_lcdc_parents[2] = { &dclk_lcdc_div, &extclk };
981 static struct clk dclk_lcdc = {
983 .clksel_con = CRU_CLKSEL16_CON,
984 .clksel_parent_mask = 1,
985 .clksel_parent_shift = 10,
986 .parents = dclk_lcdc_parents,
989 static struct clk dclk_ebook = {
990 .name = "dclk_ebook",
991 .recalc = clksel_recalc_div,
992 .set_rate = clksel_set_rate_div,
993 .clksel_con = CRU_CLKSEL16_CON,
996 .clksel_parent_mask = 3,
997 .clksel_parent_shift = 11,
998 .parents = dclk_lcdc_div_parents,
1001 static struct clk *aclk_lcdc_parents[4] = { &ddr_pll_clk, &codec_pll_clk, &periph_pll_clk, &arm_pll_clk };
1003 static struct clk aclk_lcdc = {
1004 .name = "aclk_lcdc",
1005 .recalc = clksel_recalc_div,
1006 .set_rate = clksel_set_rate_div,
1007 .clksel_con = CRU_CLKSEL16_CON,
1008 .clksel_mask = 0x1F,
1010 .clksel_parent_mask = 3,
1011 .clksel_parent_shift = 18,
1012 .parents = aclk_lcdc_parents,
1015 static struct clk hclk_lcdc = {
1016 .name = "hclk_lcdc",
1017 .parent = &aclk_lcdc,
1018 .clksel_con = CRU_CLKSEL16_CON,
1019 .recalc = clksel_recalc_shift,
1020 .set_rate = clksel_set_rate_shift,
1026 static struct clk *xpu_parents[4] = { &periph_pll_clk, &ddr_pll_clk, &codec_pll_clk, &arm_pll_clk };
1028 static struct clk aclk_vepu = {
1029 .name = "aclk_vepu",
1031 .recalc = clksel_recalc_div,
1032 .set_rate = clksel_set_rate_div,
1033 .gate_idx = CLK_GAET_VEPU_AXI,
1034 .clksel_con = CRU_CLKSEL17_CON,
1035 .clksel_mask = 0x1F,
1037 .clksel_parent_mask = 3,
1038 .clksel_parent_shift = 0,
1039 .parents = xpu_parents,
1042 static struct clk hclk_vepu = {
1043 .name = "hclk_vepu",
1044 .parent = &aclk_vepu,
1046 .recalc = clksel_recalc_shift,
1047 .set_rate = clksel_set_rate_shift,
1048 .gate_idx = CLK_GATE_VEPU_AHB,
1049 .clksel_con = CRU_CLKSEL17_CON,
1055 static struct clk aclk_vdpu = {
1056 .name = "aclk_vdpu",
1057 .parent = &periph_pll_clk,
1059 .recalc = clksel_recalc_div,
1060 .set_rate = clksel_set_rate_div,
1061 .gate_idx = CLK_GATE_VDPU_AXI,
1062 .clksel_con = CRU_CLKSEL17_CON,
1063 .clksel_mask = 0x1F,
1065 .clksel_parent_mask = 3,
1066 .clksel_parent_shift = 7,
1067 .parents = xpu_parents,
1070 static struct clk hclk_vdpu = {
1071 .name = "hclk_vdpu",
1072 .parent = &aclk_vdpu,
1074 .recalc = clksel_recalc_shift,
1075 .set_rate = clksel_set_rate_shift,
1076 .gate_idx = CLK_GATE_VDPU_AHB,
1077 .clksel_con = CRU_CLKSEL17_CON,
1083 static struct clk clk_gpu = {
1085 .recalc = clksel_recalc_div,
1086 .set_rate = clksel_set_rate_div,
1087 .clksel_con = CRU_CLKSEL17_CON,
1088 .clksel_mask = 0x1F,
1090 .clksel_parent_mask = 3,
1091 .clksel_parent_shift = 14,
1092 .parents = xpu_parents,
1095 static struct clk aclk_gpu = {
1097 .recalc = clksel_recalc_div,
1098 .set_rate = clksel_set_rate_div,
1099 .clksel_con = CRU_CLKSEL17_CON,
1100 .clksel_mask = 0x1F,
1102 .clksel_parent_mask = 3,
1103 .clksel_parent_shift = 21,
1104 .parents = xpu_parents,
1108 static struct clk *clk_vip_parents[4] = { &xin24m, &extclk, &dclk_ebook };
1110 static struct clk clk_vip = {
1113 .gate_idx = CLK_GATE_VIP,
1114 .clksel_con = CRU_CLKSEL1_CON,
1115 .clksel_parent_mask = 3,
1116 .clksel_parent_shift = 7,
1117 .parents = clk_vip_parents,
1121 #define GATE_CLK(NAME,PARENT,ID) \
1122 static struct clk clk_##NAME = { \
1124 .parent = &PARENT, \
1125 .mode = gate_mode, \
1126 .gate_idx = CLK_GATE_##ID, \
1129 #define CLK(dev, con, ck) \
1136 #define CLK1(name) \
1140 .clk = &clk_##name, \
1143 static struct clk_lookup clks[] = {
1144 CLK(NULL, "xin24m", &xin24m),
1145 CLK(NULL, "extclk", &extclk),
1146 CLK(NULL, "otgphy0_clkin", &otgphy0_clkin),
1147 CLK(NULL, "otgphy1_clkin", &otgphy1_clkin),
1148 CLK(NULL, "gpsclk", &gpsclk),
1151 CLK(NULL, "arm_pll", &arm_pll_clk),
1152 CLK(NULL, "ddr_pll", &ddr_pll_clk),
1153 CLK(NULL, "codec_pll", &codec_pll_clk),
1154 CLK(NULL, "periph_pll", &periph_pll_clk),
1157 CLK(NULL, "aclk_cpu", &aclk_cpu),
1158 CLK(NULL, "hclk_cpu", &hclk_cpu),
1159 CLK(NULL, "pclk_cpu", &pclk_cpu),
1161 CLK(NULL, "aclk_periph", &aclk_periph),
1162 CLK(NULL, "hclk_periph", &hclk_periph),
1163 CLK(NULL, "pclk_periph", &pclk_periph),
1166 CLK("rk29_otgphy.0", "otgphy", &clk_otgphy0),
1167 CLK("rk29_otgphy.1", "otgphy", &clk_otgphy1),
1168 CLK(NULL, "uhost", &clk_uhost),
1169 CLK(NULL, "mac_ref_div", &clk_mac_ref_div),
1170 CLK(NULL, "mac_ref", &clk_mac_ref),
1172 CLK("rk29_i2s.0", "i2s_div", &clk_i2s0_div),
1173 CLK("rk29_i2s.0", "i2s_frac_div", &clk_i2s0_frac_div),
1174 CLK("rk29_i2s.0", "i2s", &clk_i2s0),
1175 CLK("rk29_i2s.1", "i2s_div", &clk_i2s1_div),
1176 CLK("rk29_i2s.1", "i2s_frac_div", &clk_i2s1_frac_div),
1177 CLK("rk29_i2s.1", "i2s", &clk_i2s1),
1178 CLK(NULL, "spdif_div", &clk_spdif_div),
1179 CLK(NULL, "spdif_frac_div", &clk_spdif_frac_div),
1180 CLK(NULL, "spdif", &clk_spdif),
1183 CLK("rk29_spi.0", "spi", &clk_spi0),
1184 CLK("rk29_spi.1", "spi", &clk_spi1),
1193 CLK("rk29_sdmmc.0", "sdmmc", &clk_sdmmc0),
1194 CLK("rk29_sdmmc.1", "sdmmc", &clk_sdmmc1),
1199 CLK("rk29_serial.0", "uart", &clk_uart0),
1200 CLK("rk29_serial.0", "uart_div", &clk_uart0_div),
1201 CLK("rk29_serial.0", "uart_frac_div", &clk_uart0_frac_div),
1202 CLK("rk29_serial.1", "uart", &clk_uart1),
1203 CLK("rk29_serial.1", "uart_div", &clk_uart1_div),
1204 CLK("rk29_serial.1", "uart_frac_div", &clk_uart1_frac_div),
1207 CLK("rk29_serial.2", "uart", &clk_uart2),
1208 CLK("rk29_serial.2", "uart_div", &clk_uart2_div),
1209 CLK("rk29_serial.2", "uart_frac_div", &clk_uart2_frac_div),
1210 CLK("rk29_serial.3", "uart", &clk_uart3),
1211 CLK("rk29_serial.3", "uart_div", &clk_uart3_div),
1212 CLK("rk29_serial.3", "uart_frac_div", &clk_uart3_frac_div),
1215 CLK1(hsadc_frac_div),
1219 CLK1(hsadc_div2_inv),
1222 CLK(NULL, "dclk_lcdc_div", &dclk_lcdc_div),
1223 CLK(NULL, "dclk_lcdc", &dclk_lcdc),
1224 CLK(NULL, "dclk_ebook", &dclk_ebook),
1225 CLK(NULL, "aclk_lcdc", &aclk_lcdc),
1226 CLK(NULL, "hclk_lcdc", &hclk_lcdc),
1228 CLK(NULL, "aclk_vepu", &aclk_vepu),
1229 CLK(NULL, "hclk_vepu", &hclk_vepu),
1230 CLK(NULL, "aclk_vdpu", &aclk_vdpu),
1231 CLK(NULL, "hclk_vdpu", &hclk_vdpu),
1233 CLK(NULL, "aclk_gpu", &aclk_gpu),
1236 static LIST_HEAD(clocks);
1237 static DEFINE_MUTEX(clocks_mutex);
1238 static DEFINE_SPINLOCK(clockfw_lock);
1239 #define LOCK() do { WARN_ON(in_irq()); if (!irqs_disabled()) spin_lock_bh(&clockfw_lock); } while (0)
1240 #define UNLOCK() do { if (!irqs_disabled()) spin_unlock_bh(&clockfw_lock); } while (0)
1242 static int __clk_enable(struct clk *clk)
1246 if (clk->usecount == 0) {
1248 ret = __clk_enable(clk->parent);
1254 ret = clk->mode(clk, 1);
1257 __clk_disable(clk->parent);
1261 pr_debug("%s enabled\n", clk->name);
1268 int clk_enable(struct clk *clk)
1272 if (clk == NULL || IS_ERR(clk))
1276 ret = __clk_enable(clk);
1281 EXPORT_SYMBOL(clk_enable);
1283 static void __clk_disable(struct clk *clk)
1285 if (--clk->usecount == 0) {
1288 pr_debug("%s disabled\n", clk->name);
1290 __clk_disable(clk->parent);
1294 void clk_disable(struct clk *clk)
1296 if (clk == NULL || IS_ERR(clk))
1300 if (clk->usecount == 0) {
1301 printk(KERN_ERR "Trying disable clock %s with 0 usecount\n", clk->name);
1311 EXPORT_SYMBOL(clk_disable);
1313 unsigned long clk_get_rate(struct clk *clk)
1315 if (clk == NULL || IS_ERR(clk))
1320 EXPORT_SYMBOL(clk_get_rate);
1322 /*-------------------------------------------------------------------------
1323 * Optional clock functions defined in include/linux/clk.h
1324 *-------------------------------------------------------------------------*/
1326 /* Given a clock and a rate apply a clock specific rounding function */
1327 static long __clk_round_rate(struct clk *clk, unsigned long rate)
1329 if (clk->round_rate)
1330 return clk->round_rate(clk, rate);
1332 if (clk->flags & RATE_FIXED)
1333 printk(KERN_ERR "clock: clk_round_rate called on fixed-rate clock %s\n", clk->name);
1338 long clk_round_rate(struct clk *clk, unsigned long rate)
1342 if (clk == NULL || IS_ERR(clk))
1346 ret = __clk_round_rate(clk, rate);
1351 EXPORT_SYMBOL(clk_round_rate);
1353 /* Set the clock rate for a clock source */
1354 static int __clk_set_rate(struct clk *clk, unsigned long rate)
1358 pr_debug("set_rate for clock %s to rate %ld\n", clk->name, rate);
1360 if (clk->flags & CONFIG_PARTICIPANT)
1364 ret = clk->set_rate(clk, rate);
1369 static void __clk_recalc(struct clk *clk)
1371 if (unlikely(clk->flags & RATE_FIXED))
1374 clk->rate = clk->recalc(clk);
1375 else if (clk->parent)
1376 clk->rate = clk->parent->rate;
1379 int clk_set_rate(struct clk *clk, unsigned long rate)
1383 if (clk == NULL || IS_ERR(clk))
1387 if (rate == clk->rate) {
1391 ret = __clk_set_rate(clk, rate);
1394 __propagate_rate(clk);
1401 EXPORT_SYMBOL(clk_set_rate);
1403 int clk_set_parent(struct clk *clk, struct clk *parent)
1407 if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
1410 if (clk->set_parent == NULL && clk->parents == NULL)
1414 if (clk->usecount == 0) {
1415 if (clk->set_parent)
1416 ret = clk->set_parent(clk, parent);
1418 ret = clksel_set_parent(clk, parent);
1420 __clk_reparent(clk, parent);
1422 __propagate_rate(clk);
1430 EXPORT_SYMBOL(clk_set_parent);
1432 struct clk *clk_get_parent(struct clk *clk)
1436 EXPORT_SYMBOL(clk_get_parent);
1438 static void __clk_reparent(struct clk *child, struct clk *parent)
1440 if (child->parent == parent)
1442 pr_debug("%s reparent to %s (was %s)\n", child->name, parent->name, ((child->parent) ? child->parent->name : "NULL"));
1444 list_del_init(&child->sibling);
1446 list_add(&child->sibling, &parent->children);
1447 child->parent = parent;
1450 /* Propagate rate to children */
1451 static void __propagate_rate(struct clk *tclk)
1455 list_for_each_entry(clkp, &tclk->children, sibling) {
1457 __propagate_rate(clkp);
1461 static LIST_HEAD(root_clks);
1464 * recalculate_root_clocks - recalculate and propagate all root clocks
1466 * Recalculates all root clocks (clocks with no parent), which if the
1467 * clock's .recalc is set correctly, should also propagate their rates.
1470 static void recalculate_root_clocks(void)
1474 list_for_each_entry(clkp, &root_clks, sibling) {
1476 __propagate_rate(clkp);
1480 void clk_recalculate_root_clocks(void)
1483 recalculate_root_clocks();
1489 * clk_preinit - initialize any fields in the struct clk before clk init
1490 * @clk: struct clk * to initialize
1492 * Initialize any struct clk fields needed before normal clk initialization
1493 * can run. No return value.
1495 static void clk_preinit(struct clk *clk)
1497 INIT_LIST_HEAD(&clk->children);
1500 static int clk_register(struct clk *clk)
1502 if (clk == NULL || IS_ERR(clk))
1506 * trap out already registered clocks
1508 if (clk->node.next || clk->node.prev)
1511 mutex_lock(&clocks_mutex);
1513 if (clk->get_parent)
1514 clk->parent = clk->get_parent(clk);
1515 else if (clk->parents)
1516 clk->parent = clksel_get_parent(clk);
1519 list_add(&clk->sibling, &clk->parent->children);
1521 list_add(&clk->sibling, &root_clks);
1523 list_add(&clk->node, &clocks);
1525 mutex_unlock(&clocks_mutex);
1530 static void clk_enable_init_clocks(void)
1534 list_for_each_entry(clkp, &clocks, node) {
1535 if (clkp->flags & ENABLE_ON_INIT)
1540 void __init rk29_clock_init(void)
1542 struct clk_lookup *lk;
1544 for (lk = clks; lk < clks + ARRAY_SIZE(clks); lk++)
1545 clk_preinit(lk->clk);
1547 for (lk = clks; lk < clks + ARRAY_SIZE(clks); lk++) {
1549 clk_register(lk->clk);
1552 recalculate_root_clocks();
1554 printk(KERN_INFO "Clocking rate (apll/dpll/cpll/ppll/core/aclk/hclk/pclk): %ld/%ld/%ld/%ld/%ld/%ld/%ld/%ld MHz\n",
1555 arm_pll_clk.rate / 1000000, ddr_pll_clk.rate / 1000000, codec_pll_clk.rate / 1000000, periph_pll_clk.rate / 1000000,
1556 clk_core.rate / 1000000, aclk_cpu.rate / 1000000, hclk_cpu.rate / 1000000, pclk_cpu.rate / 1000000);
1559 * Only enable those clocks we will need, let the drivers
1560 * enable other clocks as necessary
1562 clk_enable_init_clocks();
1565 #ifdef CONFIG_PROC_FS
1566 #include <linux/proc_fs.h>
1567 #include <linux/seq_file.h>
1569 static void dump_clock(struct seq_file *s, struct clk *clk, int deep)
1573 unsigned long rate = clk->rate;
1575 for (i = 0; i < deep; i++)
1578 seq_printf(s, "%-9s ", clk->name);
1580 if (clk->mode && (clk->gate_idx < CLK_GATE_MAX)) {
1582 int idx = clk->gate_idx;
1585 reg = CRU_CLKGATE0_CON;
1586 reg += (idx >> 5) << 2;
1589 v = cru_readl(reg) & (1 << idx);
1591 seq_printf(s, "%s ", v ? "off" : "on ");
1594 if (rate >= 1000000) {
1596 seq_printf(s, "%ld.%06ld MHz", rate / 1000000, rate % 1000000);
1598 seq_printf(s, "%ld MHz", rate / 1000000);
1599 } else if (rate >= 1000) {
1601 seq_printf(s, "%ld.%03ld KHz", rate / 1000, rate % 1000);
1603 seq_printf(s, "%ld KHz", rate / 1000);
1605 seq_printf(s, "%ld Hz", rate);
1608 seq_printf(s, " usecount = %d", clk->usecount);
1610 seq_printf(s, " parent = %s\n", clk->parent ? clk->parent->name : "NULL");
1612 list_for_each_entry(ck, &clocks, node) {
1613 if (ck->parent == clk)
1614 dump_clock(s, ck, deep + 1);
1618 static int proc_clk_show(struct seq_file *s, void *v)
1622 mutex_lock(&clocks_mutex);
1623 list_for_each_entry(clk, &clocks, node) {
1625 dump_clock(s, clk, 0);
1627 mutex_unlock(&clocks_mutex);
1629 seq_printf(s, "\nRegisters:\n");
1630 seq_printf(s, "APLL : 0x%08x\n", cru_readl(CRU_APLL_CON));
1631 seq_printf(s, "DPLL : 0x%08x\n", cru_readl(CRU_DPLL_CON));
1632 seq_printf(s, "CPLL : 0x%08x\n", cru_readl(CRU_CPLL_CON));
1633 seq_printf(s, "PPLL : 0x%08x\n", cru_readl(CRU_PPLL_CON));
1634 seq_printf(s, "MODE : 0x%08x\n", cru_readl(CRU_MODE_CON));
1635 seq_printf(s, "CLKSEL0 : 0x%08x\n", cru_readl(CRU_CLKSEL0_CON));
1636 seq_printf(s, "CLKSEL1 : 0x%08x\n", cru_readl(CRU_CLKSEL1_CON));
1637 seq_printf(s, "CLKSEL2 : 0x%08x\n", cru_readl(CRU_CLKSEL2_CON));
1638 seq_printf(s, "CLKSEL3 : 0x%08x\n", cru_readl(CRU_CLKSEL3_CON));
1639 seq_printf(s, "CLKSEL4 : 0x%08x\n", cru_readl(CRU_CLKSEL4_CON));
1640 seq_printf(s, "CLKSEL5 : 0x%08x\n", cru_readl(CRU_CLKSEL5_CON));
1641 seq_printf(s, "CLKSEL6 : 0x%08x\n", cru_readl(CRU_CLKSEL6_CON));
1642 seq_printf(s, "CLKSEL7 : 0x%08x\n", cru_readl(CRU_CLKSEL7_CON));
1643 seq_printf(s, "CLKSEL8 : 0x%08x\n", cru_readl(CRU_CLKSEL8_CON));
1644 seq_printf(s, "CLKSEL9 : 0x%08x\n", cru_readl(CRU_CLKSEL9_CON));
1645 seq_printf(s, "CLKSEL10 : 0x%08x\n", cru_readl(CRU_CLKSEL10_CON));
1646 seq_printf(s, "CLKSEL11 : 0x%08x\n", cru_readl(CRU_CLKSEL11_CON));
1647 seq_printf(s, "CLKSEL12 : 0x%08x\n", cru_readl(CRU_CLKSEL12_CON));
1648 seq_printf(s, "CLKSEL13 : 0x%08x\n", cru_readl(CRU_CLKSEL13_CON));
1649 seq_printf(s, "CLKSEL14 : 0x%08x\n", cru_readl(CRU_CLKSEL14_CON));
1650 seq_printf(s, "CLKSEL15 : 0x%08x\n", cru_readl(CRU_CLKSEL15_CON));
1651 seq_printf(s, "CLKSEL16 : 0x%08x\n", cru_readl(CRU_CLKSEL16_CON));
1652 seq_printf(s, "CLKSEL17 : 0x%08x\n", cru_readl(CRU_CLKSEL17_CON));
1653 seq_printf(s, "CLKGATE0 : 0x%08x\n", cru_readl(CRU_CLKGATE0_CON));
1654 seq_printf(s, "CLKGATE1 : 0x%08x\n", cru_readl(CRU_CLKGATE1_CON));
1655 seq_printf(s, "CLKGATE2 : 0x%08x\n", cru_readl(CRU_CLKGATE2_CON));
1656 seq_printf(s, "CLKGATE3 : 0x%08x\n", cru_readl(CRU_CLKGATE3_CON));
1661 static int proc_clk_open(struct inode *inode, struct file *file)
1663 return single_open(file, proc_clk_show, NULL);
1666 static const struct file_operations proc_clk_fops = {
1667 .open = proc_clk_open,
1669 .llseek = seq_lseek,
1670 .release = single_release,
1673 static int __init clk_proc_init(void)
1675 proc_create("clocks", 0, NULL, &proc_clk_fops);
1679 late_initcall(clk_proc_init);
1680 #endif /* CONFIG_PROC_FS */