Date:2011-03-18 16:18:03 (13 years 10 days ago)
Author:Lars C.
Commit:c1e9dbcf81ff9a0c04b99748874ae7d088d5ac59
Message:MIPS: JZ47XX: Further generalize clock support

Share common clock management functions and structs between the sub-archs.
Also use clkdev for clock lookup, which allows us to assign a clock to a device
which is usful if we have multiple device instances of the same driver. (Like
for the MMC driver).
Files: arch/mips/Kconfig (1 diff)
arch/mips/include/asm/clkdev.h (1 diff)
arch/mips/include/asm/mach-jz47xx/clkdev.h (1 diff)
arch/mips/jz47xx/Makefile (1 diff)
arch/mips/jz47xx/clock.c (1 diff)
arch/mips/jz47xx/clock.h (3 diffs)
arch/mips/jz47xx/jz4740/clock.c (9 diffs)
arch/mips/jz47xx/jz4750/clock-jz4750l.c (7 diffs)
arch/mips/jz47xx/jz4760/clock.c (11 diffs)

Change Details

arch/mips/Kconfig
210210    select SYS_HAS_EARLY_PRINTK
211211    select HAVE_PWM
212212    select HAVE_CLK
213    select CLKDEV_LOOKUP
213214
214215config LASAT
215216    bool "LASAT Networks platforms"
arch/mips/include/asm/clkdev.h
1#ifndef __ASM_CLKDEV_H
2#define __ASM_CLKDEV_H
3
4#include <clkdev.h>
5
6#endif
arch/mips/include/asm/mach-jz47xx/clkdev.h
1#ifndef __ASM_MACH_JZ47XX_CLKDEV_H__
2#define __ASM_MACH_JZ47XX_CLKDEV_H__
3
4#include <linux/slab.h>
5#define __clk_get(clk) ({ 1; })
6#define __clk_put(clk) do { } while (0)
7
8static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
9{
10    return kzalloc(size, GFP_KERNEL);
11}
12
13#endif
arch/mips/jz47xx/Makefile
55# Object file lists.
66
77obj-y += prom.o irq.o reset.o setup.o \
8    timer.o pwm.o serial.o
8    timer.o pwm.o serial.o clock.o
99
1010obj-$(CONFIG_JZ47XX_TIMER_CSRC) += timer-csrc.o
1111obj-$(CONFIG_JZ47XX_TIMER_CEVT) += timer-cevt.o
arch/mips/jz47xx/clock.c
1#include <linux/kernel.h>
2#include <linux/errno.h>
3#include <linux/clk.h>
4#include <linux/spinlock.h>
5#include <linux/io.h>
6#include <linux/module.h>
7#include <linux/list.h>
8#include <linux/err.h>
9
10#include <asm/mach-jz47xx/clock.h>
11
12#include <asm/mach-jz47xx/base.h>
13
14#include "clock.h"
15
16int clk_enable(struct clk *clk)
17{
18    if (!clk->ops->enable)
19        return -EINVAL;
20
21    return clk->ops->enable(clk);
22}
23EXPORT_SYMBOL_GPL(clk_enable);
24
25void clk_disable(struct clk *clk)
26{
27    if (clk->ops->disable)
28        clk->ops->disable(clk);
29}
30EXPORT_SYMBOL_GPL(clk_disable);
31
32int clk_is_enabled(struct clk *clk)
33{
34    if (clk->ops->is_enabled)
35        return clk->ops->is_enabled(clk);
36
37    return 1;
38}
39
40unsigned long clk_get_rate(struct clk *clk)
41{
42    if (clk->ops->get_rate)
43        return clk->ops->get_rate(clk);
44    if (clk->parent)
45        return clk_get_rate(clk->parent);
46
47    return -EINVAL;
48}
49EXPORT_SYMBOL_GPL(clk_get_rate);
50
51int clk_set_rate(struct clk *clk, unsigned long rate)
52{
53    if (!clk->ops->set_rate)
54        return -EINVAL;
55
56    return clk->ops->set_rate(clk, rate);
57}
58EXPORT_SYMBOL_GPL(clk_set_rate);
59
60long clk_round_rate(struct clk *clk, unsigned long rate)
61{
62    if (!clk->ops->round_rate)
63        return -EINVAL;
64
65    return clk->ops->round_rate(clk, rate);
66}
67EXPORT_SYMBOL_GPL(clk_round_rate);
68
69int clk_set_parent(struct clk *clk, struct clk *parent)
70{
71    int ret;
72    int enabled;
73
74    if (!clk->ops->set_parent)
75        return -EINVAL;
76
77    enabled = clk_is_enabled(clk);
78    if (enabled)
79        clk_disable(clk);
80    ret = clk->ops->set_parent(clk, parent);
81    if (enabled)
82        clk_enable(clk);
83
84    jz4740_clock_debugfs_update_parent(clk);
85
86    return ret;
87}
88EXPORT_SYMBOL_GPL(clk_set_parent);
89
90void __init jz47xx_clock_add_table(struct clk_lookup *table, size_t num)
91{
92    size_t i;
93
94    clkdev_add_table(table, num);
95
96    for (i = 0; i < num; ++i)
97        jz4740_clock_debugfs_add_clk(table[i].clk);
98}
arch/mips/jz47xx/clock.h
1717#define __MIPS_JZ4740_CLOCK_H__
1818
1919#include <linux/list.h>
20#include <linux/clkdev.h>
2021
2122struct jz47xx_clock_board_data {
2223    unsigned long ext_rate;
...... 
3940    int (*is_enabled)(struct clk *clk);
4041
4142    int (*set_parent)(struct clk *clk, struct clk *parent);
42
4343};
4444
4545struct clk {
46    const char *name;
4746    struct clk *parent;
4847
4948    uint32_t gate_bit;
5049
51    const struct clk_ops *ops;
50    const char *name;
5251
53    struct list_head list;
52    const struct clk_ops *ops;
5453
5554#ifdef CONFIG_DEBUG_FS
5655    struct dentry *debugfs_entry;
...... 
6160
6261#define JZ47XX_CLK_NOT_GATED ((uint32_t)-1)
6362
63struct main_clk {
64    struct clk clk;
65    uint32_t div_offset;
66};
67
68struct divided_clk {
69    struct clk clk;
70    uint32_t reg;
71    uint32_t mask;
72};
73
74struct static_clk {
75    struct clk clk;
76    unsigned long rate;
77};
78
79void __init jz47xx_clock_add_table(struct clk_lookup *table, size_t num);
6480int clk_is_enabled(struct clk *clk);
6581
6682#ifdef CONFIG_DEBUG_FS
arch/mips/jz47xx/jz4740/clock.c
9999
100100static void __iomem *jz_clock_base;
101101static spinlock_t jz_clock_lock;
102static LIST_HEAD(jz_clocks);
103
104struct main_clk {
105    struct clk clk;
106    uint32_t div_offset;
107};
108
109struct divided_clk {
110    struct clk clk;
111    uint32_t reg;
112    uint32_t mask;
113};
114
115struct static_clk {
116    struct clk clk;
117    unsigned long rate;
118};
119102
120103static uint32_t jz_clk_reg_read(int reg)
121104{
122105    return readl(jz_clock_base + reg);
123106}
124107
125static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
108static void jz_clk_reg_write_mask(unsigned int reg, uint32_t val, uint32_t mask)
126109{
127110    uint32_t val2;
128111
...... 
134117    spin_unlock(&jz_clock_lock);
135118}
136119
137static void jz_clk_reg_set_bits(int reg, uint32_t mask)
120static void jz_clk_reg_set_bits(unsigned int reg, uint32_t mask)
138121{
139122    uint32_t val;
140123
...... 
145128    spin_unlock(&jz_clock_lock);
146129}
147130
148static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
131static void jz_clk_reg_clear_bits(unsigned int reg, uint32_t mask)
149132{
150133    uint32_t val;
151134
...... 
430413            JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
431414}
432415
433static int jz_clk_udc_enable(struct clk *clk)
434{
435    jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
436
437    return 0;
438}
439
440static int jz_clk_udc_disable(struct clk *clk)
441{
442    jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
443
444    return 0;
445}
446
447static int jz_clk_udc_is_enabled(struct clk *clk)
448{
449    return !!(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & JZ_CLOCK_GATE_UDC);
450}
451
452416static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
453417{
454418    if (parent == &jz_clk_pll_half)
...... 
617581    .is_enabled = jz_clk_is_enabled_gating,
618582};
619583
620static struct divided_clk jz4740_clock_divided_clks[] = {
621    [0] = {
622        .clk = {
623            .name = "i2s",
624            .parent = &jz_clk_ext.clk,
625            .gate_bit = JZ_CLOCK_GATE_I2S,
626            .ops = &jz_clk_i2s_ops,
627        },
628        .reg = JZ_REG_CLOCK_I2S,
629        .mask = JZ_CLOCK_I2S_DIV_MASK,
584
585static struct divided_clk jz_clk_i2s = {
586    .clk = {
587        .name = "i2s",
588        .parent = &jz_clk_ext.clk,
589        .gate_bit = JZ_CLOCK_GATE_I2S,
590        .ops = &jz_clk_i2s_ops,
630591    },
631    [1] = {
632        .clk = {
633            .name = "spi",
634            .parent = &jz_clk_ext.clk,
635            .gate_bit = JZ_CLOCK_GATE_SPI,
636            .ops = &jz_clk_spi_ops,
637        },
638        .reg = JZ_REG_CLOCK_SPI,
639        .mask = JZ_CLOCK_SPI_DIV_MASK,
592    .reg = JZ_REG_CLOCK_I2S,
593    .mask = JZ_CLOCK_I2S_DIV_MASK,
594};
595
596static struct divided_clk jz_clk_spi = {
597    .clk = {
598        .name = "spi",
599        .parent = &jz_clk_ext.clk,
600        .gate_bit = JZ_CLOCK_GATE_SPI,
601        .ops = &jz_clk_spi_ops,
640602    },
641    [2] = {
642        .clk = {
643            .name = "lcd_pclk",
644            .parent = &jz_clk_pll_half,
645            .gate_bit = JZ47XX_CLK_NOT_GATED,
646            .ops = &jz_clk_divided_ops,
647        },
648        .reg = JZ_REG_CLOCK_LCD,
649        .mask = JZ_CLOCK_LCD_DIV_MASK,
603    .reg = JZ_REG_CLOCK_SPI,
604    .mask = JZ_CLOCK_SPI_DIV_MASK,
605};
606
607
608static struct divided_clk jz_clk_lcd_pclk = {
609    .clk = {
610        .name = "lcd_pclk",
611        .parent = &jz_clk_pll_half,
612        .gate_bit = JZ47XX_CLK_NOT_GATED,
613        .ops = &jz_clk_divided_ops,
650614    },
651    [3] = {
652        .clk = {
653            .name = "mmc",
654            .parent = &jz_clk_pll_half,
655            .gate_bit = JZ_CLOCK_GATE_MMC,
656            .ops = &jz_clk_divided_ops,
657        },
658        .reg = JZ_REG_CLOCK_MMC,
659        .mask = JZ_CLOCK_MMC_DIV_MASK,
615    .reg = JZ_REG_CLOCK_LCD,
616    .mask = JZ_CLOCK_LCD_DIV_MASK,
617};
618
619static struct divided_clk jz_clk_mmc = {
620    .clk = {
621        .name = "mmc",
622        .parent = &jz_clk_pll_half,
623        .gate_bit = JZ_CLOCK_GATE_MMC,
624        .ops = &jz_clk_divided_ops,
660625    },
661    [4] = {
662        .clk = {
663            .name = "uhc",
664            .parent = &jz_clk_pll_half,
665            .gate_bit = JZ_CLOCK_GATE_UHC,
666            .ops = &jz_clk_divided_ops,
667        },
668        .reg = JZ_REG_CLOCK_UHC,
669        .mask = JZ_CLOCK_UHC_DIV_MASK,
626    .reg = JZ_REG_CLOCK_MMC,
627    .mask = JZ_CLOCK_MMC_DIV_MASK,
628};
629
630static struct divided_clk jz_clk_uhc = {
631    .clk = {
632        .name = "uhc",
633        .parent = &jz_clk_pll_half,
634        .gate_bit = JZ_CLOCK_GATE_UHC,
635        .ops = &jz_clk_divided_ops,
670636    },
637    .reg = JZ_REG_CLOCK_UHC,
638    .mask = JZ_CLOCK_UHC_DIV_MASK,
671639};
672640
673641static const struct clk_ops jz_clk_udc_phy_ops = {
...... 
680648    .set_parent = jz_clk_udc_set_parent,
681649    .set_rate = jz_clk_udc_set_rate,
682650    .get_rate = jz_clk_udc_get_rate,
683    .enable = jz_clk_udc_enable,
684    .disable = jz_clk_udc_disable,
685    .is_enabled = jz_clk_udc_is_enabled,
651    .enable = jz_clk_enable_gating,
652    .disable = jz_clk_disable_gating,
653    .is_enabled = jz_clk_is_enabled_gating,
686654};
687655
688656static const struct clk_ops jz_clk_simple_ops = {
...... 
691659    .is_enabled = jz_clk_is_enabled_gating,
692660};
693661
694static struct clk jz4740_clock_simple_clks[] = {
695    [0] = {
696        .name = "udc",
697        .parent = &jz_clk_ext.clk,
698        .ops = &jz_clk_udc_ops,
699    },
700    [1] = {
701        .name = "uart0",
702        .parent = &jz_clk_ext.clk,
703        .gate_bit = JZ_CLOCK_GATE_UART0,
704        .ops = &jz_clk_simple_ops,
705    },
706    [2] = {
707        .name = "uart1",
708        .parent = &jz_clk_ext.clk,
709        .gate_bit = JZ_CLOCK_GATE_UART1,
710        .ops = &jz_clk_simple_ops,
711    },
712    [3] = {
713        .name = "dma",
714        .parent = &jz_clk_high_speed_peripheral.clk,
715        .gate_bit = JZ_CLOCK_GATE_UART0,
716        .ops = &jz_clk_simple_ops,
717    },
718    [4] = {
719        .name = "ipu",
720        .parent = &jz_clk_high_speed_peripheral.clk,
721        .gate_bit = JZ_CLOCK_GATE_IPU,
722        .ops = &jz_clk_simple_ops,
723    },
724    [5] = {
725        .name = "adc",
726        .parent = &jz_clk_ext.clk,
727        .gate_bit = JZ_CLOCK_GATE_ADC,
728        .ops = &jz_clk_simple_ops,
729    },
730    [6] = {
731        .name = "i2c",
732        .parent = &jz_clk_ext.clk,
733        .gate_bit = JZ_CLOCK_GATE_I2C,
734        .ops = &jz_clk_simple_ops,
735    },
736    [7] = {
737        .name = "aic",
738        .parent = &jz_clk_ext.clk,
739        .gate_bit = JZ_CLOCK_GATE_AIC,
740        .ops = &jz_clk_simple_ops,
741    },
742    [8] = {
743        .name = "udc-phy",
744        .parent = &jz4740_clock_simple_clks[0], /* udc */
745        .ops = &jz_clk_udc_phy_ops,
746    },
662static struct clk jz_clk_udc = {
663    .name = "udc",
664    .parent = &jz_clk_ext.clk,
665    .gate_bit = JZ_CLOCK_GATE_UDC,
666    .ops = &jz_clk_udc_ops,
747667};
748668
749static struct static_clk jz_clk_rtc = {
750    .clk = {
751        .name = "rtc",
752        .gate_bit = JZ_CLOCK_GATE_RTC,
753        .ops = &jz_clk_static_ops,
754    },
755    .rate = 32768,
669static struct clk jz_clk_uart0 = {
670    .name = "uart0",
671    .parent = &jz_clk_ext.clk,
672    .gate_bit = JZ_CLOCK_GATE_UART0,
673    .ops = &jz_clk_simple_ops,
756674};
757675
758int clk_enable(struct clk *clk)
759{
760    if (!clk->ops->enable)
761        return -EINVAL;
762
763    return clk->ops->enable(clk);
764}
765EXPORT_SYMBOL_GPL(clk_enable);
766
767void clk_disable(struct clk *clk)
768{
769    if (clk->ops->disable)
770        clk->ops->disable(clk);
771}
772EXPORT_SYMBOL_GPL(clk_disable);
773
774int clk_is_enabled(struct clk *clk)
775{
776    if (clk->ops->is_enabled)
777        return clk->ops->is_enabled(clk);
778
779    return 1;
780}
781
782unsigned long clk_get_rate(struct clk *clk)
783{
784    if (clk->ops->get_rate)
785        return clk->ops->get_rate(clk);
786    if (clk->parent)
787        return clk_get_rate(clk->parent);
788
789    return -EINVAL;
790}
791EXPORT_SYMBOL_GPL(clk_get_rate);
792
793int clk_set_rate(struct clk *clk, unsigned long rate)
794{
795    if (!clk->ops->set_rate)
796        return -EINVAL;
797    return clk->ops->set_rate(clk, rate);
798}
799EXPORT_SYMBOL_GPL(clk_set_rate);
800
801long clk_round_rate(struct clk *clk, unsigned long rate)
802{
803    if (clk->ops->round_rate)
804        return clk->ops->round_rate(clk, rate);
805
806    return -EINVAL;
807}
808EXPORT_SYMBOL_GPL(clk_round_rate);
809
810int clk_set_parent(struct clk *clk, struct clk *parent)
811{
812    int ret;
813    int enabled;
814
815    if (!clk->ops->set_parent)
816        return -EINVAL;
676static struct clk jz_clk_uart1 = {
677    .name = "uart1",
678    .parent = &jz_clk_ext.clk,
679    .gate_bit = JZ_CLOCK_GATE_UART1,
680    .ops = &jz_clk_simple_ops,
681};
817682
818    enabled = clk_is_enabled(clk);
819    if (enabled)
820        clk_disable(clk);
821    ret = clk->ops->set_parent(clk, parent);
822    if (enabled)
823        clk_enable(clk);
683static struct clk jz_clk_dma = {
684    .name = "dma",
685    .parent = &jz_clk_high_speed_peripheral.clk,
686    .gate_bit = JZ_CLOCK_GATE_DMAC,
687    .ops = &jz_clk_simple_ops,
688};
824689
825    jz4740_clock_debugfs_update_parent(clk);
690static struct clk jz_clk_ipu = {
691    .name = "ipu",
692    .parent = &jz_clk_high_speed_peripheral.clk,
693    .gate_bit = JZ_CLOCK_GATE_IPU,
694    .ops = &jz_clk_simple_ops,
695};
826696
827    return ret;
828}
829EXPORT_SYMBOL_GPL(clk_set_parent);
697static struct clk jz_clk_adc = {
698    .name = "adc",
699    .parent = &jz_clk_ext.clk,
700    .gate_bit = JZ_CLOCK_GATE_ADC,
701    .ops = &jz_clk_simple_ops,
702};
830703
831struct clk *clk_get(struct device *dev, const char *name)
832{
833    struct clk *clk;
704static struct clk jz_clk_i2c = {
705    .name = "i2c",
706    .parent = &jz_clk_ext.clk,
707    .gate_bit = JZ_CLOCK_GATE_I2C,
708    .ops = &jz_clk_simple_ops,
709};
834710
835    list_for_each_entry(clk, &jz_clocks, list) {
836        if (strcmp(clk->name, name) == 0)
837            return clk;
838    }
839    return ERR_PTR(-ENXIO);
840}
841EXPORT_SYMBOL_GPL(clk_get);
711static struct clk jz_clk_aic = {
712    .name = "aic",
713    .parent = &jz_clk_ext.clk,
714    .gate_bit = JZ_CLOCK_GATE_AIC,
715    .ops = &jz_clk_simple_ops,
716};
842717
843void clk_put(struct clk *clk)
844{
845}
846EXPORT_SYMBOL_GPL(clk_put);
718static struct clk jz_clk_udc_phy = {
719    .name = "udc-phy",
720    .parent = &jz_clk_udc, /* udc */
721    .ops = &jz_clk_udc_phy_ops,
722};
847723
848static inline void clk_add(struct clk *clk)
849{
850    list_add_tail(&clk->list, &jz_clocks);
724static struct static_clk jz_clk_rtc = {
725    .clk = {
726        .name = "rtc",
727        .gate_bit = JZ_CLOCK_GATE_RTC,
728        .ops = &jz_clk_static_ops,
729    },
730    .rate = 32768,
731};
851732
852    jz4740_clock_debugfs_add_clk(clk);
853}
733#define INIT_CLOCK(_dev, _con, _clk) \
734    { .dev_id = _dev, .con_id = _con, .clk = _clk, }
735
736static struct clk_lookup jz4740_clk_table[] = {
737    INIT_CLOCK(NULL, "ext", &jz_clk_ext.clk),
738    INIT_CLOCK(NULL, "pll", &jz_clk_pll),
739    INIT_CLOCK(NULL, "pll half", &jz_clk_pll_half),
740    INIT_CLOCK(NULL, "cclk", &jz_clk_cpu.clk),
741    INIT_CLOCK(NULL, "mclk", &jz_clk_memory.clk),
742    INIT_CLOCK(NULL, "hclk", &jz_clk_high_speed_peripheral.clk),
743    INIT_CLOCK(NULL, "pclk", &jz_clk_low_speed_peripheral.clk),
744    INIT_CLOCK(NULL, "cko", &jz_clk_ko),
745
746    INIT_CLOCK("jz4740-rtc", "rtc", &jz_clk_rtc.clk),
747    INIT_CLOCK("jz4740-fb", "lcd", &jz_clk_ld),
748    INIT_CLOCK("jz4740-fb", "lcd_pclk", &jz_clk_lcd_pclk.clk),
749    INIT_CLOCK(NULL, "spi", &jz_clk_spi.clk),
750    INIT_CLOCK(NULL, "i2c", &jz_clk_i2c),
751    INIT_CLOCK("jz4740-i2s", "i2s", &jz_clk_i2s.clk),
752    INIT_CLOCK("jz4740-i2s", "aic", &jz_clk_aic),
753    INIT_CLOCK("jz4740-adc", "adc", &jz_clk_adc),
754    INIT_CLOCK("jz-udc", "udc", &jz_clk_udc),
755    INIT_CLOCK("jz-udc", "udc-phy", &jz_clk_udc_phy),
756    INIT_CLOCK("jz4740-mmc", "mmc", &jz_clk_mmc.clk),
757    INIT_CLOCK("jz4740-ohci", "uhc", &jz_clk_uhc.clk),
758
759    INIT_CLOCK(NULL, "uart0", &jz_clk_uart0),
760    INIT_CLOCK(NULL, "uart1", &jz_clk_uart1),
761    INIT_CLOCK(NULL, "dma", &jz_clk_dma),
762    INIT_CLOCK(NULL, "ipu", &jz_clk_ipu),
763};
854764
855765static void clk_register_clks(void)
856766{
857    size_t i;
858
859    clk_add(&jz_clk_ext.clk);
860    clk_add(&jz_clk_pll);
861    clk_add(&jz_clk_pll_half);
862    clk_add(&jz_clk_cpu.clk);
863    clk_add(&jz_clk_high_speed_peripheral.clk);
864    clk_add(&jz_clk_low_speed_peripheral.clk);
865    clk_add(&jz_clk_ko);
866    clk_add(&jz_clk_ld);
867    clk_add(&jz_clk_rtc.clk);
868
869    for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
870        clk_add(&jz4740_clock_divided_clks[i].clk);
871
872    for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
873        clk_add(&jz4740_clock_simple_clks[i]);
767    jz47xx_clock_add_table(jz4740_clk_table, ARRAY_SIZE(jz4740_clk_table));
874768}
875769
876770void jz47xx_clock_set_wait_mode(enum jz47xx_wait_mode mode)
...... 
907801        JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
908802}
909803
910static int jz4740_clock_init(void)
804static int __init jz4740_clock_init(void)
911805{
912806    uint32_t val;
913807
...... 
923817    val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
924818
925819    if (val & JZ_CLOCK_SPI_SRC_PLL)
926        jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
820        jz_clk_spi.clk.parent = &jz_clk_pll_half;
927821
928822    val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
929823
930824    if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
931        jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
825        jz_clk_i2s.clk.parent = &jz_clk_pll_half;
932826
933827    if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
934        jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
828        jz_clk_udc.parent = &jz_clk_pll_half;
935829
936830    jz4740_clock_debugfs_init();
937831
arch/mips/jz47xx/jz4750/clock-jz4750l.c
115115
116116static void __iomem *jz_clock_base;
117117static spinlock_t jz_clock_lock;
118static LIST_HEAD(jz_clocks);
119
120struct main_clk {
121    struct clk clk;
122    uint32_t div_offset;
123};
124
125struct divided_clk {
126    struct clk clk;
127    uint32_t reg;
128    uint32_t mask;
129};
130
131struct static_clk {
132    struct clk clk;
133    unsigned long rate;
134};
135118
136119static uint32_t jz_clk_reg_read(int reg)
137120{
...... 
366349    .div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
367350};
368351
369static struct main_clk jz_clk_ipu = {
352static struct main_clk jz4750_clk_ipu = {
370353    .clk = {
371354        .name = "ipuclk",
372355        .parent = &jz_clk_pll,
...... 
547530    .is_enabled = jz_clk_is_enabled_gating,
548531};
549532
550static struct divided_clk jz4750_clock_divided_clks[] = {
551    [0] = {
552        .clk = {
553            .name = "i2s",
554            .parent = &jz_clk_ext.clk,
555            .gate_bit = JZ47XX_CLK_NOT_GATED,
556            .ops = &jz_clk_i2s_ops,
557        },
558        .reg = JZ_REG_CLOCK_I2S,
559        .mask = JZ_CLOCK_I2S_DIV_MASK,
533static struct divided_clk jz4750_clk_i2s = {
534    .clk = {
535        .name = "i2s",
536        .parent = &jz_clk_ext.clk,
537        .gate_bit = JZ47XX_CLK_NOT_GATED,
538        .ops = &jz_clk_i2s_ops,
560539    },
561    [1] = {
562        .clk = {
563            .name = "spi",
564            .parent = &jz_clk_ext.clk,
565            .gate_bit = JZ_CLOCK_GATE_SPI,
566            .ops = &jz_clk_spi_ops,
567        },
568        .reg = JZ_REG_CLOCK_SPI,
569        .mask = JZ_CLOCK_SPI_DIV_MASK,
540    .reg = JZ_REG_CLOCK_I2S,
541    .mask = JZ_CLOCK_I2S_DIV_MASK,
542};
543
544static struct divided_clk jz4750_clk_spi = {
545    .clk = {
546        .name = "spi",
547        .parent = &jz_clk_ext.clk,
548        .gate_bit = JZ_CLOCK_GATE_SPI,
549        .ops = &jz_clk_spi_ops,
570550    },
571    [2] = {
572        .clk = {
573            .name = "lcd",
574            .parent = &jz_clk_pll_half,
575            .gate_bit = JZ_CLOCK_GATE_LCD,
576            .ops = &jz_clk_divided_ops,
577        },
578        .reg = JZ_REG_CLOCK_LCD,
579        .mask = JZ_CLOCK_LCD_DIV_MASK,
551    .reg = JZ_REG_CLOCK_SPI,
552    .mask = JZ_CLOCK_SPI_DIV_MASK,
553};
554
555static struct divided_clk jz4750_clk_lcd = {
556    .clk = {
557        .name = "lcd",
558        .parent = &jz_clk_pll_half,
559        .gate_bit = JZ_CLOCK_GATE_LCD,
560        .ops = &jz_clk_divided_ops,
580561    },
581    [3] = {
582        .clk = {
583            .name = "mmc0",
584            .parent = &jz_clk_pll_half,
585            .gate_bit = JZ_CLOCK_GATE_MMC0,
586            .ops = &jz_clk_divided_ops,
587        },
588        .reg = JZ_REG_CLOCK_MMC,
589        .mask = JZ_CLOCK_MMC_DIV_MASK,
562    .reg = JZ_REG_CLOCK_LCD,
563    .mask = JZ_CLOCK_LCD_DIV_MASK,
564};
565
566static struct divided_clk jz4750_clk_mmc0 = {
567    .clk = {
568        .name = "mmc0",
569        .parent = &jz_clk_pll_half,
570        .gate_bit = JZ_CLOCK_GATE_MMC0,
571        .ops = &jz_clk_divided_ops,
590572    },
591    [4] = {
592        .clk = {
593            .name = "mmc1",
594            .parent = &jz_clk_pll_half,
595            .gate_bit = JZ_CLOCK_GATE_MMC1,
596            .ops = &jz_clk_divided_ops,
597        },
598        /* MMC0 and MMC1 have same divisor, but separate gates */
599        .reg = JZ_REG_CLOCK_MMC,
600        .mask = JZ_CLOCK_MMC_DIV_MASK,
573    .reg = JZ_REG_CLOCK_MMC,
574    .mask = JZ_CLOCK_MMC_DIV_MASK,
575};
576
577static struct divided_clk jz4750_clk_mmc1 = {
578    .clk = {
579        .name = "mmc1",
580        .parent = &jz_clk_pll_half,
581        .gate_bit = JZ_CLOCK_GATE_MMC1,
582        .ops = &jz_clk_divided_ops,
601583    },
602    [5] = {
603        .clk = {
604            .name = "uhc",
605            .parent = &jz_clk_pll_half,
606            .gate_bit = JZ_CLOCK_GATE_UHC,
607            .ops = &jz_clk_divided_ops,
608        },
609        .reg = JZ_REG_CLOCK_UHC,
610        .mask = JZ_CLOCK_UHC_DIV_MASK,
584    /* MMC0 and MMC1 have same divisor, but separate gates */
585    .reg = JZ_REG_CLOCK_MMC,
586    .mask = JZ_CLOCK_MMC_DIV_MASK,
587};
588
589static struct divided_clk jz4750_clk_uhc = {
590    .clk = {
591        .name = "uhc",
592        .parent = &jz_clk_pll_half,
593        .gate_bit = JZ_CLOCK_GATE_UHC,
594        .ops = &jz_clk_divided_ops,
611595    },
596    .reg = JZ_REG_CLOCK_UHC,
597    .mask = JZ_CLOCK_UHC_DIV_MASK,
612598};
613599
614600static const struct clk_ops jz_clk_udc_phy_ops = {
...... 
632618    .is_enabled = jz_clk_is_enabled_gating,
633619};
634620
635static struct clk jz4750_clock_simple_clks[] = {
636    [0] = {
637        .name = "udc",
638        .parent = &jz_clk_ext.clk,
639        .ops = &jz_clk_udc_ops,
640    },
641    [1] = {
642        .name = "uart0",
643        .parent = &jz_clk_ext.clk,
644        .gate_bit = JZ_CLOCK_GATE_UART0,
645        .ops = &jz_clk_simple_ops,
646    },
647    [2] = {
648        .name = "uart1",
649        .parent = &jz_clk_ext.clk,
650        .gate_bit = JZ_CLOCK_GATE_UART1,
651        .ops = &jz_clk_simple_ops,
652    },
653    [3] = {
654        .name = "dma",
655        .parent = &jz_clk_high_speed_peripheral.clk,
656        .gate_bit = JZ_CLOCK_GATE_DMAC,
657        .ops = &jz_clk_simple_ops,
658    },
659    [4] = {
660        .name = "adc",
661        .parent = &jz_clk_ext.clk,
662        .gate_bit = JZ_CLOCK_GATE_ADC,
663        .ops = &jz_clk_simple_ops,
664    },
665    [5] = {
666        .name = "i2c",
667        .parent = &jz_clk_ext.clk,
668        .gate_bit = JZ_CLOCK_GATE_I2C,
669        .ops = &jz_clk_simple_ops,
670    },
671    [6] = {
672        .name = "aic",
673        .parent = &jz_clk_ext.clk,
674        .gate_bit = JZ_CLOCK_GATE_AIC,
675        .ops = &jz_clk_simple_ops,
676    },
677    [7] = {
678        .name = "udc-phy",
679        .parent = &jz4750_clock_simple_clks[0], /* udc */
680        .gate_bit = JZ47XX_CLK_NOT_GATED,
681        .ops = &jz_clk_udc_phy_ops,
682    },
683    [8] = {
684        .name = "bch",
685        .parent = &jz_clk_low_speed_peripheral.clk,
686        .gate_bit = JZ_CLOCK_GATE_BCH,
687        .ops = &jz_clk_simple_ops,
688    },
621static struct clk jz4750_clk_udc = {
622    .name = "udc",
623    .parent = &jz_clk_ext.clk,
624    .ops = &jz_clk_udc_ops,
689625};
690626
691static struct static_clk jz_clk_rtc = {
692    .clk = {
693        .name = "rtc",
694        .gate_bit = JZ_CLOCK_GATE_RTC,
695        .ops = &jz_clk_static_ops,
696    },
697    .rate = 32768,
627static struct clk jz4750_clk_uart0 = {
628    .name = "uart0",
629    .parent = &jz_clk_ext.clk,
630    .gate_bit = JZ_CLOCK_GATE_UART0,
631    .ops = &jz_clk_simple_ops,
698632};
699633
700int clk_enable(struct clk *clk)
701{
702    if (!clk->ops->enable)
703        return -EINVAL;
704
705    return clk->ops->enable(clk);
706}
707EXPORT_SYMBOL_GPL(clk_enable);
708
709void clk_disable(struct clk *clk)
710{
711    if (clk->ops->disable)
712        clk->ops->disable(clk);
713}
714EXPORT_SYMBOL_GPL(clk_disable);
715
716int clk_is_enabled(struct clk *clk)
717{
718    if (clk->ops->is_enabled)
719        return clk->ops->is_enabled(clk);
720
721    return 1;
722}
634static struct clk jz4750_clk_uart1 = {
635    .name = "uart1",
636    .parent = &jz_clk_ext.clk,
637    .gate_bit = JZ_CLOCK_GATE_UART1,
638    .ops = &jz_clk_simple_ops,
639};
723640
724unsigned long clk_get_rate(struct clk *clk)
725{
726    if (clk->ops->get_rate)
727        return clk->ops->get_rate(clk);
728    if (clk->parent)
729        return clk_get_rate(clk->parent);
641static struct clk jz4750_clk_dma = {
642    .name = "dma",
643    .parent = &jz_clk_high_speed_peripheral.clk,
644    .gate_bit = JZ_CLOCK_GATE_DMAC,
645    .ops = &jz_clk_simple_ops,
646};
730647
731    return -EINVAL;
732}
733EXPORT_SYMBOL_GPL(clk_get_rate);
648static struct clk jz4750_clk_adc = {
649    .name = "adc",
650    .parent = &jz_clk_ext.clk,
651    .gate_bit = JZ_CLOCK_GATE_ADC,
652    .ops = &jz_clk_simple_ops,
653};
734654
735int clk_set_rate(struct clk *clk, unsigned long rate)
736{
737    if (!clk->ops->set_rate)
738        return -EINVAL;
739    return clk->ops->set_rate(clk, rate);
740}
741EXPORT_SYMBOL_GPL(clk_set_rate);
655static struct clk jz4750_clk_i2c = {
656    .name = "i2c",
657    .parent = &jz_clk_ext.clk,
658    .gate_bit = JZ_CLOCK_GATE_I2C,
659    .ops = &jz_clk_simple_ops,
660};
742661
743long clk_round_rate(struct clk *clk, unsigned long rate)
744{
745    if (clk->ops->round_rate)
746        return clk->ops->round_rate(clk, rate);
662static struct clk jz4750_clk_aic = {
663    .name = "aic",
664    .parent = &jz_clk_ext.clk,
665    .gate_bit = JZ_CLOCK_GATE_AIC,
666    .ops = &jz_clk_simple_ops,
667};
747668
748    return -EINVAL;
749}
750EXPORT_SYMBOL_GPL(clk_round_rate);
669static struct clk jz4750_clk_udc_phy = {
670    .name = "udc-phy",
671    .parent = &jz4750_clk_udc,
672    .gate_bit = JZ47XX_CLK_NOT_GATED,
673    .ops = &jz_clk_udc_phy_ops,
674};
751675
752int clk_set_parent(struct clk *clk, struct clk *parent)
753{
754    int ret;
755    int enabled;
676static struct clk jz4750_clk_bch = {
677    .name = "bch",
678    .parent = &jz_clk_low_speed_peripheral.clk,
679    .gate_bit = JZ_CLOCK_GATE_BCH,
680    .ops = &jz_clk_simple_ops,
681};
756682
757    if (!clk->ops->set_parent)
758        return -EINVAL;
683static struct static_clk jz4750_clk_rtc = {
684    .clk = {
685        .name = "rtc",
686        .gate_bit = JZ_CLOCK_GATE_RTC,
687        .ops = &jz_clk_static_ops,
688    },
689    .rate = 32768,
690};
759691
760    enabled = clk_is_enabled(clk);
761    if (enabled)
762        clk_disable(clk);
763    ret = clk->ops->set_parent(clk, parent);
764    if (enabled)
765        clk_enable(clk);
692#define INIT_CLOCK(_dev, _con, _clk) \
693    { .dev_id = _dev, .con_id = _con, .clk = _clk, }
766694
767    jz4740_clock_debugfs_update_parent(clk);
695static struct clk_lookup jz4750_clk_table[] = {
696    INIT_CLOCK(NULL, "ext", &jz_clk_ext.clk),
697    INIT_CLOCK(NULL, "pll", &jz_clk_pll),
698    INIT_CLOCK(NULL, "pll half", &jz_clk_pll_half),
699    INIT_CLOCK(NULL, "cclk", &jz_clk_cpu.clk),
700    INIT_CLOCK(NULL, "mclk", &jz_clk_memory.clk),
701    INIT_CLOCK(NULL, "hclk", &jz_clk_high_speed_peripheral.clk),
702    INIT_CLOCK(NULL, "pclk", &jz_clk_low_speed_peripheral.clk),
768703
769    return ret;
770}
771EXPORT_SYMBOL_GPL(clk_set_parent);
704    INIT_CLOCK("jz4750-nand", "bch", &jz4750_clk_bch),
772705
773struct clk *clk_get(struct device *dev, const char *name)
774{
775    struct clk *clk;
706    INIT_CLOCK("jz4740-rtc", "rtc", &jz4750_clk_rtc.clk),
707    INIT_CLOCK("jz4740-fb", "lcd", &jz4750_clk_lcd.clk),
708    INIT_CLOCK(NULL, "spi", &jz4750_clk_spi.clk),
776709
777    list_for_each_entry(clk, &jz_clocks, list) {
778        if (strcmp(clk->name, name) == 0)
779            return clk;
780    }
781    return ERR_PTR(-ENXIO);
782}
783EXPORT_SYMBOL_GPL(clk_get);
710    INIT_CLOCK(NULL, "i2c", &jz4750_clk_i2c),
784711
785void clk_put(struct clk *clk)
786{
787}
788EXPORT_SYMBOL_GPL(clk_put);
712    INIT_CLOCK("jz4740-i2s", "i2s", &jz4750_clk_i2s.clk),
713    INIT_CLOCK("jz4740-i2s", "aic", &jz4750_clk_aic),
789714
790static inline void clk_add(struct clk *clk)
791{
792    list_add_tail(&clk->list, &jz_clocks);
715    INIT_CLOCK("jz4740-adc", "adc", &jz4750_clk_adc),
716    INIT_CLOCK("jz-udc", "udc", &jz4750_clk_udc),
717    INIT_CLOCK("jz-udc", "udc-phy", &jz4750_clk_udc_phy),
718    INIT_CLOCK("jz4740-mmc.0", "mmc", &jz4750_clk_mmc0.clk),
719    INIT_CLOCK("jz4740-mmc.1", "mmc", &jz4750_clk_mmc1.clk),
720    INIT_CLOCK("jz4740-ohci", "uhc", &jz4750_clk_uhc.clk),
793721
794    jz4740_clock_debugfs_add_clk(clk);
795}
722    INIT_CLOCK(NULL, "uart0", &jz4750_clk_uart0),
723    INIT_CLOCK(NULL, "uart1", &jz4750_clk_uart1),
724    INIT_CLOCK(NULL, "dma", &jz4750_clk_dma),
725    INIT_CLOCK(NULL, "ipu", &jz4750_clk_ipu.clk),
726};
796727
797static void clk_register_clks(void)
728static void __init clk_register_clks(void)
798729{
799    size_t i;
800
801    clk_add(&jz_clk_ext.clk);
802    clk_add(&jz_clk_pll);
803    clk_add(&jz_clk_pll_half);
804    clk_add(&jz_clk_cpu.clk);
805    clk_add(&jz_clk_high_speed_peripheral.clk);
806    clk_add(&jz_clk_low_speed_peripheral.clk);
807    clk_add(&jz_clk_memory.clk);
808    clk_add(&jz_clk_ipu.clk);
809    clk_add(&jz_clk_rtc.clk);
810
811    for (i = 0; i < ARRAY_SIZE(jz4750_clock_divided_clks); ++i)
812        clk_add(&jz4750_clock_divided_clks[i].clk);
813
814    for (i = 0; i < ARRAY_SIZE(jz4750_clock_simple_clks); ++i)
815        clk_add(&jz4750_clock_simple_clks[i]);
730    jz47xx_clock_add_table(jz4750_clk_table, ARRAY_SIZE(jz4750_clk_table));
816731}
817732
818733void jz47xx_clock_set_wait_mode(enum jz47xx_wait_mode mode)
...... 
849764        JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
850765}
851766
852static int jz4750_clock_init(void)
767static int __init jz4750_clock_init(void)
853768{
854769    uint32_t val;
855770
...... 
860775    spin_lock_init(&jz_clock_lock);
861776
862777    jz_clk_ext.rate = jz47xx_clock_bdata.ext_rate;
863    jz_clk_rtc.rate = jz47xx_clock_bdata.rtc_rate;
778    jz4750_clk_rtc.rate = jz47xx_clock_bdata.rtc_rate;
864779
865780    jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CHANGE_ENABLE);
866781
...... 
870785    val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
871786
872787    if (val & JZ_CLOCK_SPI_SRC_PLL)
873        jz4750_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
788        jz4750_clk_spi.clk.parent = &jz_clk_pll_half;
874789
875790    val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
876791
877792    if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
878        jz4750_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
793        jz4750_clk_i2s.clk.parent = &jz_clk_pll_half;
879794
880795    if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
881        jz4750_clock_simple_clks[0].parent = &jz_clk_pll_half;
796        jz4750_clk_udc.parent = &jz_clk_pll_half;
882797
883798    jz4740_clock_debugfs_init();
884799
arch/mips/jz47xx/jz4760/clock.c
2222#include <linux/list.h>
2323#include <linux/err.h>
2424
25#include <jz4740/clock.h>
26
25#include <asm/mach-jz47xx/clock.h>
2726#include <asm/mach-jz47xx/base.h>
2827
2928#include "../clock.h"
...... 
3130#define JZ_REG_CLOCK_CTRL 0x00
3231#define JZ_REG_CLOCK_LOW_POWER 0x04
3332#define JZ_REG_CLOCK_PLL 0x10
34#define JZ_REG_CLOCK_GATE 0x20
33#define JZ_REG_CLOCK_GATE0 0x20
34#define JZ_REG_CLOCK_GATE1 0x28
3535#define JZ_REG_CLOCK_SLEEP_CTRL 0x24
3636#define JZ_REG_CLOCK_I2S 0x60
3737#define JZ_REG_CLOCK_LCD 0x64
38#define JZ_REG_CLOCK_MMC 0x68
38#define JZ_REG_CLOCK_MSC 0x68
3939#define JZ_REG_CLOCK_UHC 0x6C
40#define JZ_REG_CLOCK_SPI 0x74
40#define JZ_REG_CLOCK_SSI 0x74
4141
42#define JZ_CLOCK_CTRL_I2S_SRC_PLL BIT(31)
43#define JZ_CLOCK_CTRL_KO_ENABLE BIT(30)
44#define JZ_CLOCK_CTRL_UDC_SRC_PLL BIT(29)
45#define JZ_CLOCK_CTRL_UDIV_MASK 0x1f800000
4642#define JZ_CLOCK_CTRL_CHANGE_ENABLE BIT(22)
4743#define JZ_CLOCK_CTRL_PLL_HALF BIT(21)
4844#define JZ_CLOCK_CTRL_LDIV_MASK 0x001f0000
49#define JZ_CLOCK_CTRL_UDIV_OFFSET 23
50#define JZ_CLOCK_CTRL_LDIV_OFFSET 16
45#define JZ_CLOCK_CTRL_SDIV_OFFSET 24
46#define JZ_CLOCK_CTRL_H2DIV_OFFSET 16
5147#define JZ_CLOCK_CTRL_MDIV_OFFSET 12
5248#define JZ_CLOCK_CTRL_PDIV_OFFSET 8
5349#define JZ_CLOCK_CTRL_HDIV_OFFSET 4
5450#define JZ_CLOCK_CTRL_CDIV_OFFSET 0
5551
56#define JZ_CLOCK_GATE_UART0 BIT(0)
57#define JZ_CLOCK_GATE_TCU BIT(1)
58#define JZ_CLOCK_GATE_RTC BIT(2)
59#define JZ_CLOCK_GATE_I2C BIT(3)
60#define JZ_CLOCK_GATE_SPI BIT(4)
61#define JZ_CLOCK_GATE_AIC BIT(5)
62#define JZ_CLOCK_GATE_I2S BIT(6)
63#define JZ_CLOCK_GATE_MMC BIT(7)
64#define JZ_CLOCK_GATE_ADC BIT(8)
65#define JZ_CLOCK_GATE_CIM BIT(9)
66#define JZ_CLOCK_GATE_LCD BIT(10)
67#define JZ_CLOCK_GATE_UDC BIT(11)
68#define JZ_CLOCK_GATE_DMAC BIT(12)
69#define JZ_CLOCK_GATE_IPU BIT(13)
70#define JZ_CLOCK_GATE_UHC BIT(14)
71#define JZ_CLOCK_GATE_UART1 BIT(15)
72
52#define JZ_CLOCK_GATE0_NMEC BIT(0)
53#define JZ_CLOCK_GATE0_BCH BIT(1)
54#define JZ_CLOCK_GATE0_OTG BIT(2)
55#define JZ_CLOCK_GATE0_MSC0 BIT(3)
56#define JZ_CLOCK_GATE0_SSI0 BIT(4)
57#define JZ_CLOCK_GATE0_I2C0 BIT(5)
58#define JZ_CLOCK_GATE0_I2C1 BIT(6)
59#define JZ_CLOCK_GATE0_SCC BIT(7)
60#define JZ_CLOCK_GATE0_AIC BIT(8)
61#define JZ_CLOCK_GATE0_TSSI BIT(9)
62#define JZ_CLOCK_GATE0_OWI BIT(10)
63#define JZ_CLOCK_GATE0_MSC1 BIT(11)
64#define JZ_CLOCK_GATE0_MSC2 BIT(12)
65#define JZ_CLOCK_GATE0_KBC BIT(13)
66#define JZ_CLOCK_GATE0_SADC BIT(14)
67#define JZ_CLOCK_GATE0_UART0 BIT(15)
68#define JZ_CLOCK_GATE0_UART1 BIT(16)
69#define JZ_CLOCK_GATE0_UART2 BIT(17)
70#define JZ_CLOCK_GATE0_UART3 BIT(18)
71#define JZ_CLOCK_GATE0_SSI1 BIT(19)
72#define JZ_CLOCK_GATE0_SSI2 BIT(20)
73#define JZ_CLOCK_GATE0_DMAC BIT(21)
74#define JZ_CLOCK_GATE0_GPS BIT(22)
75#define JZ_CLOCK_GATE0_MAC BIT(23)
76#define JZ_CLOCK_GATE0_UHC BIT(24)
77#define JZ_CLOCK_GATE0_MDMA BIT(25)
78#define JZ_CLOCK_GATE0_CIM BIT(26)
79#define JZ_CLOCK_GATE0_TVE BIT(27)
80#define JZ_CLOCK_GATE0_LCD BIT(28)
81#define JZ_CLOCK_GATE0_IPU BIT(29)
82#define JZ_CLOCK_GATE0_DDR BIT(30)
83#define JZ_CLOCK_GATE0_EMC BIT(31)
84
85#define JZ_CLOCK_GATE1_GPU BIT(9)
86#define JZ_CLOCK_GATE1_PCM BIT(8)
87#define JZ_CLOCK_GATE1_AHB1 BIT(7)
88#define JZ_CLOCK_GATE1_CABAC BIT(6)
89#define JZ_CLOCK_GATE1_SRAM BIT(5)
90#define JZ_CLOCK_GATE1_DCT BIT(4)
91#define JZ_CLOCK_GATE1_ME BIT(3)
92#define JZ_CLOCK_GATE1_DBLK BIT(2)
93#define JZ_CLOCK_GATE1_MC BIT(1)
94#define JZ_CLOCK_GATE1_BDMA BIT(0)
95
96
97#define JZ_CLOCK_I2S_SRC_PLL BIT(31)
98#define JZ_CLOCK_I2S_SRC_PLL1 BIT(30)
7399#define JZ_CLOCK_I2S_DIV_MASK 0x01ff
74100
75#define JZ_CLOCK_LCD_DIV_MASK 0x01ff
101#define JZ_CLOCK_UDC_SRC_PLL BIT(31)
102#define JZ_CLOCK_UDC_SRC_PLL1 BIT(30)
103#define JZ_CLOCK_UDC_DIV_MASK 0x003f
76104
77#define JZ_CLOCK_MMC_DIV_MASK 0x001f
105#define JZ_CLOCK_LCD_SRC_PLL1 BIT(29)
106#define JZ_CLOCK_LCD_DIV_MASK 0x07ff
78107
108#define JZ_CLOCK_MSC_SRC_PLL0 BIT(31)
109#define JZ_CLOCK_MSC_DIV_MASK 0x001f
110
111#define JZ_CLOCK_UHC_SRC_PLL1 BIT(31)
79112#define JZ_CLOCK_UHC_DIV_MASK 0x000f
80113
81#define JZ_CLOCK_SPI_SRC_PLL BIT(31)
82#define JZ_CLOCK_SPI_DIV_MASK 0x000f
114#define JZ_CLOCK_SSI_SRC_PLL0 BIT(31)
115#define JZ_CLOCK_SSI_DIV_MASK 0x001f
83116
84#define JZ_CLOCK_PLL_M_MASK 0x01ff
117#define JZ_CLOCK_PLL_M_MASK 0x003f
85118#define JZ_CLOCK_PLL_N_MASK 0x001f
86119#define JZ_CLOCK_PLL_OD_MASK 0x0003
87120#define JZ_CLOCK_PLL_STABLE BIT(10)
...... 
95128#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
96129#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
97130
98#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
99#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
131#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(5)
132#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(7)
100133
101134static void __iomem *jz_clock_base;
102135static spinlock_t jz_clock_lock;
103static LIST_HEAD(jz_clocks);
104
105struct main_clk {
106    struct clk clk;
107    uint32_t div_offset;
108};
109
110struct divided_clk {
111    struct clk clk;
112    uint32_t reg;
113    uint32_t mask;
114};
115
116struct static_clk {
117    struct clk clk;
118    unsigned long rate;
119};
120136
121137static uint32_t jz_clk_reg_read(int reg)
122138{
...... 
157173    spin_unlock(&jz_clock_lock);
158174}
159175
160static int jz_clk_enable_gating(struct clk *clk)
176static int jz_clk_enable_gating(struct clk *clk, unsigned int reg)
161177{
162    if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
178    if (clk->gate_bit == JZ47XX_CLK_NOT_GATED)
163179        return -EINVAL;
164180
165    jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
181    jz_clk_reg_clear_bits(reg, clk->gate_bit);
166182    return 0;
167183}
168184
169static int jz_clk_disable_gating(struct clk *clk)
185static int jz_clk_disable_gating(struct clk *clk, unsigned int reg)
170186{
171    if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
187    if (clk->gate_bit == JZ47XX_CLK_NOT_GATED)
172188        return -EINVAL;
173189
174    jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
190    jz_clk_reg_set_bits(reg, clk->gate_bit);
175191    return 0;
176192}
177193
178static int jz_clk_is_enabled_gating(struct clk *clk)
194static int jz_clk_is_enabled_gating(struct clk *clk, unsigned int reg)
179195{
180    if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
196    if (clk->gate_bit == JZ47XX_CLK_NOT_GATED)
181197        return 1;
182198
183    return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
199    return !(jz_clk_reg_read(reg) & clk->gate_bit);
184200}
185201
186static unsigned long jz_clk_static_get_rate(struct clk *clk)
202static int jz_clk_enable_gating0(struct clk *clk)
187203{
188    return ((struct static_clk *)clk)->rate;
204    return jz_clk_enable_gating(clk, JZ_REG_CLOCK_GATE0);
189205}
190206
191static int jz_clk_ko_enable(struct clk *clk)
207static int jz_clk_disable_gating0(struct clk *clk)
192208{
193    jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
194    return 0;
209    return jz_clk_disable_gating(clk, JZ_REG_CLOCK_GATE0);
195210}
196211
197static int jz_clk_ko_disable(struct clk *clk)
212static int jz_clk_is_enabled_gating0(struct clk *clk)
198213{
199    jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
200    return 0;
214    return jz_clk_is_enabled_gating(clk, JZ_REG_CLOCK_GATE0);
201215}
202216
203static int jz_clk_ko_is_enabled(struct clk *clk)
217static int jz_clk_enable_gating1(struct clk *clk)
204218{
205    return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
219    return jz_clk_enable_gating(clk, JZ_REG_CLOCK_GATE1);
206220}
207221
208static const int pllno[] = {1, 2, 2, 4};
222static int jz_clk_disable_gating1(struct clk *clk)
223{
224    return jz_clk_disable_gating(clk, JZ_REG_CLOCK_GATE1);
225}
226
227static int jz_clk_is_enabled_gating1(struct clk *clk)
228{
229    return jz_clk_is_enabled_gating(clk, JZ_REG_CLOCK_GATE1);
230}
231
232static unsigned long jz_clk_static_get_rate(struct clk *clk)
233{
234    return ((struct static_clk *)clk)->rate;
235}
209236
210237static unsigned long jz_clk_pll_get_rate(struct clk *clk)
211238{
239    unsigned long rate;
212240    uint32_t val;
213241    int m;
214242    int n;
...... 
219247    if (val & JZ_CLOCK_PLL_BYPASS)
220248        return clk_get_rate(clk->parent);
221249
222    m = ((val >> 23) & 0x1ff) + 2;
223    n = ((val >> 18) & 0x1f) + 2;
250    m = ((val >> 23) & 0xfe);
251    n = ((val >> 18) & 0xf);
224252    od = (val >> 16) & 0x3;
225253
226    return ((clk_get_rate(clk->parent) / n) * m) / pllno[od];
254    rate = ((clk_get_rate(clk->parent) / n) * m) / (1 << od);
255
256    printk("pll rate: %d %d %d %lu\n", m, n, od, rate);
257
258    return rate;
227259}
228260
229261static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
...... 
293325
294326static struct clk_ops jz_clk_static_ops = {
295327    .get_rate = jz_clk_static_get_rate,
296    .enable = jz_clk_enable_gating,
297    .disable = jz_clk_disable_gating,
298    .is_enabled = jz_clk_is_enabled_gating,
328    .enable = jz_clk_enable_gating0,
329    .disable = jz_clk_disable_gating0,
330    .is_enabled = jz_clk_is_enabled_gating0,
299331};
300332
301333static struct static_clk jz_clk_ext = {
302334    .clk = {
303335        .name = "ext",
304        .gate_bit = JZ4740_CLK_NOT_GATED,
336        .gate_bit = JZ47XX_CLK_NOT_GATED,
305337        .ops = &jz_clk_static_ops,
306338    },
307339};
...... 
359391    .div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
360392};
361393
362
363394static struct main_clk jz_clk_low_speed_peripheral = {
364395    .clk = {
365396        .name = "pclk",
...... 
369400    .div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
370401};
371402
372static const struct clk_ops jz_clk_ko_ops = {
373    .enable = jz_clk_ko_enable,
374    .disable = jz_clk_ko_disable,
375    .is_enabled = jz_clk_ko_is_enabled,
403static struct main_clk jz_clk_high_speed_peripheral2 = {
404    .clk = {
405        .name = "h2clk",
406        .parent = &jz_clk_pll,
407        .ops = &jz_clk_main_ops,
408    },
409    .div_offset = JZ_CLOCK_CTRL_H2DIV_OFFSET,
376410};
377411
378static struct clk jz_clk_ko = {
379    .name = "cko",
380    .parent = &jz_clk_memory.clk,
381    .ops = &jz_clk_ko_ops,
412static struct main_clk jz_clk_static_peripheral = {
413    .clk = {
414        .name = "sclk",
415        .parent = &jz_clk_pll,
416        .ops = &jz_clk_main_ops,
417    },
418    .div_offset = JZ_CLOCK_CTRL_SDIV_OFFSET,
382419};
383420
384static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
385{
386    if (parent == &jz_clk_pll)
387        jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
388    else if (parent == &jz_clk_ext.clk)
389        jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
390    else
391        return -EINVAL;
392
393    clk->parent = parent;
394
395    return 0;
396}
397
398static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
399{
400    if (parent == &jz_clk_pll_half)
401        jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
402    else if (parent == &jz_clk_ext.clk)
403        jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
404    else
405        return -EINVAL;
406
407    clk->parent = parent;
408
409    return 0;
410}
411
412static int jz_clk_udc_enable(struct clk *clk)
413{
414    jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
415            JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
416
417    return 0;
418}
419
420static int jz_clk_udc_disable(struct clk *clk)
421{
422    jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
423            JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
424
425    return 0;
426}
427
428static int jz_clk_udc_is_enabled(struct clk *clk)
429{
430    return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
431            JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
432}
433
434static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
435{
436    if (parent == &jz_clk_pll_half)
437        jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
438    else if (parent == &jz_clk_ext.clk)
439        jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
440    else
441        return -EINVAL;
442
443    clk->parent = parent;
444
445    return 0;
446}
447
448static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
449{
450    int div;
451
452    if (clk->parent == &jz_clk_ext.clk)
453        return -EINVAL;
454
455    div = clk_get_rate(clk->parent) / rate - 1;
456
457    if (div < 0)
458        div = 0;
459    else if (div > 63)
460        div = 63;
461
462    jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
463                JZ_CLOCK_CTRL_UDIV_MASK);
464    return 0;
465}
466
467static unsigned long jz_clk_udc_get_rate(struct clk *clk)
468{
469    int div;
470
471    if (clk->parent == &jz_clk_ext.clk)
472        return clk_get_rate(clk->parent);
473
474    div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
475    div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
476    div += 1;
477
478    return clk_get_rate(clk->parent) / div;
479}
480
481421static unsigned long jz_clk_divided_get_rate(struct clk *clk)
482422{
483423    struct divided_clk *dclk = (struct divided_clk *)clk;
...... 
508448
509449    jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
510450
511    return 0;
512}
513
514static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
515{
516    int div;
517    unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
518
519    if (rate > 150000000)
520        return 150000000;
521
522    div = parent_rate / rate;
523    if (div < 1)
524        div = 1;
525    else if (div > 32)
526        div = 32;
527
528    return parent_rate / div;
529}
530
531static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
532{
533    int div;
534
535    if (rate > 150000000)
536        return -EINVAL;
537
538    div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
539    if (div < 0)
540        div = 0;
541    else if (div > 31)
542        div = 31;
543
544    jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
545                JZ_CLOCK_CTRL_LDIV_MASK);
451    printk("%s rate: %lu %lu\n", clk->name, rate, clk_get_rate(clk));
546452
547453    return 0;
548454}
549455
550static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
551{
552    int div;
553
554    div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
555    div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
556
557    return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
558}
559
560static const struct clk_ops jz_clk_ops_ld = {
561    .set_rate = jz_clk_ldclk_set_rate,
562    .get_rate = jz_clk_ldclk_get_rate,
563    .round_rate = jz_clk_ldclk_round_rate,
564    .enable = jz_clk_enable_gating,
565    .disable = jz_clk_disable_gating,
566    .is_enabled = jz_clk_is_enabled_gating,
567};
568
569static struct clk jz_clk_ld = {
570    .name = "lcd",
571    .gate_bit = JZ_CLOCK_GATE_LCD,
572    .parent = &jz_clk_pll_half,
573    .ops = &jz_clk_ops_ld,
574};
575
576static const struct clk_ops jz_clk_i2s_ops = {
456static const struct clk_ops jz_clk_divided_ops = {
577457    .set_rate = jz_clk_divided_set_rate,
578458    .get_rate = jz_clk_divided_get_rate,
579    .enable = jz_clk_enable_gating,
580    .disable = jz_clk_disable_gating,
581    .is_enabled = jz_clk_is_enabled_gating,
582    .set_parent = jz_clk_i2s_set_parent,
459    .enable = jz_clk_enable_gating0,
460    .disable = jz_clk_disable_gating0,
461    .is_enabled = jz_clk_is_enabled_gating0,
583462};
584463
585static const struct clk_ops jz_clk_spi_ops = {
586    .set_rate = jz_clk_divided_set_rate,
587    .get_rate = jz_clk_divided_get_rate,
588    .enable = jz_clk_enable_gating,
589    .disable = jz_clk_disable_gating,
590    .is_enabled = jz_clk_is_enabled_gating,
591    .set_parent = jz_clk_spi_set_parent,
464static struct divided_clk jz_clk_i2s = {
465    .clk = {
466        .name = "i2s",
467        .parent = &jz_clk_ext.clk,
468        .gate_bit = JZ47XX_CLK_NOT_GATED,
469        .ops = &jz_clk_divided_ops,
470    },
471    .reg = JZ_REG_CLOCK_I2S,
472    .mask = JZ_CLOCK_I2S_DIV_MASK,
592473};
593474
594static const struct clk_ops jz_clk_divided_ops = {
595    .set_rate = jz_clk_divided_set_rate,
596    .get_rate = jz_clk_divided_get_rate,
597    .enable = jz_clk_enable_gating,
598    .disable = jz_clk_disable_gating,
599    .is_enabled = jz_clk_is_enabled_gating,
600};
601
602static struct divided_clk jz4740_clock_divided_clks[] = {
603    [0] = {
604        .clk = {
605            .name = "i2s",
606            .parent = &jz_clk_ext.clk,
607            .gate_bit = JZ_CLOCK_GATE_I2S,
608            .ops = &jz_clk_i2s_ops,
609        },
610        .reg = JZ_REG_CLOCK_I2S,
611        .mask = JZ_CLOCK_I2S_DIV_MASK,
612    },
613    [1] = {
614        .clk = {
615            .name = "spi",
616            .parent = &jz_clk_ext.clk,
617            .gate_bit = JZ_CLOCK_GATE_SPI,
618            .ops = &jz_clk_spi_ops,
619        },
620        .reg = JZ_REG_CLOCK_SPI,
621        .mask = JZ_CLOCK_SPI_DIV_MASK,
475static struct divided_clk jz_clk_lcd_pclk = {
476    .clk = {
477        .name = "lcd_pclk",
478        .parent = &jz_clk_pll_half,
479        .gate_bit = JZ47XX_CLK_NOT_GATED,
480        .ops = &jz_clk_divided_ops,
622481    },
623    [2] = {
624        .clk = {
625            .name = "lcd_pclk",
626            .parent = &jz_clk_pll_half,
627            .gate_bit = JZ4740_CLK_NOT_GATED,
628            .ops = &jz_clk_divided_ops,
629        },
630        .reg = JZ_REG_CLOCK_LCD,
631        .mask = JZ_CLOCK_LCD_DIV_MASK,
482    .reg = JZ_REG_CLOCK_LCD,
483    .mask = JZ_CLOCK_LCD_DIV_MASK,
484};
485
486static struct divided_clk jz_clk_msc = {
487    .clk = {
488        .name = "msc",
489        .parent = &jz_clk_ext.clk,
490        .gate_bit = JZ47XX_CLK_NOT_GATED,
491        .ops = &jz_clk_divided_ops,
632492    },
633    [3] = {
634        .clk = {
635            .name = "mmc",
636            .parent = &jz_clk_pll_half,
637            .gate_bit = JZ_CLOCK_GATE_MMC,
638            .ops = &jz_clk_divided_ops,
639        },
640        .reg = JZ_REG_CLOCK_MMC,
641        .mask = JZ_CLOCK_MMC_DIV_MASK,
493    .reg = JZ_REG_CLOCK_MSC,
494    .mask = JZ_CLOCK_MSC_DIV_MASK,
495};
496
497static struct divided_clk jz_clk_uhc = {
498    .clk = {
499        .name = "uhc",
500        .parent = &jz_clk_pll_half,
501        .gate_bit = JZ_CLOCK_GATE0_UHC,
502        .ops = &jz_clk_divided_ops,
642503    },
643    [4] = {
644        .clk = {
645            .name = "uhc",
646            .parent = &jz_clk_pll_half,
647            .gate_bit = JZ_CLOCK_GATE_UHC,
648            .ops = &jz_clk_divided_ops,
649        },
650        .reg = JZ_REG_CLOCK_UHC,
651        .mask = JZ_CLOCK_UHC_DIV_MASK,
504    .reg = JZ_REG_CLOCK_UHC,
505    .mask = JZ_CLOCK_UHC_DIV_MASK,
506};
507
508static struct divided_clk jz_clk_ssi = {
509    .clk = {
510        .name = "ssi",
511        .parent = &jz_clk_pll_half,
512        .gate_bit = JZ47XX_CLK_NOT_GATED,
513        .ops = &jz_clk_divided_ops,
652514    },
515    .reg = JZ_REG_CLOCK_SSI,
516    .mask = JZ_CLOCK_SSI_DIV_MASK,
653517};
654518
655static const struct clk_ops jz_clk_udc_ops = {
656    .set_parent = jz_clk_udc_set_parent,
657    .set_rate = jz_clk_udc_set_rate,
658    .get_rate = jz_clk_udc_get_rate,
659    .enable = jz_clk_udc_enable,
660    .disable = jz_clk_udc_disable,
661    .is_enabled = jz_clk_udc_is_enabled,
519static const struct clk_ops jz_clk_simple0_ops = {
520    .enable = jz_clk_enable_gating0,
521    .disable = jz_clk_disable_gating0,
522    .is_enabled = jz_clk_is_enabled_gating0,
662523};
663524
664static const struct clk_ops jz_clk_simple_ops = {
665    .enable = jz_clk_enable_gating,
666    .disable = jz_clk_disable_gating,
667    .is_enabled = jz_clk_is_enabled_gating,
525static const struct clk_ops jz_clk_simple1_ops = {
526    .enable = jz_clk_enable_gating1,
527    .disable = jz_clk_disable_gating1,
528    .is_enabled = jz_clk_is_enabled_gating1,
668529};
669530
670static struct clk jz4740_clock_simple_clks[] = {
671    [0] = {
672        .name = "udc",
673        .parent = &jz_clk_ext.clk,
674        .ops = &jz_clk_udc_ops,
675    },
676    [1] = {
677        .name = "uart0",
678        .parent = &jz_clk_ext.clk,
679        .gate_bit = JZ_CLOCK_GATE_UART0,
680        .ops = &jz_clk_simple_ops,
681    },
682    [2] = {
683        .name = "uart1",
684        .parent = &jz_clk_ext.clk,
685        .gate_bit = JZ_CLOCK_GATE_UART1,
686        .ops = &jz_clk_simple_ops,
687    },
688    [3] = {
689        .name = "dma",
690        .parent = &jz_clk_high_speed_peripheral.clk,
691        .gate_bit = JZ_CLOCK_GATE_UART0,
692        .ops = &jz_clk_simple_ops,
693    },
694    [4] = {
695        .name = "ipu",
696        .parent = &jz_clk_high_speed_peripheral.clk,
697        .gate_bit = JZ_CLOCK_GATE_IPU,
698        .ops = &jz_clk_simple_ops,
699    },
700    [5] = {
701        .name = "adc",
702        .parent = &jz_clk_ext.clk,
703        .gate_bit = JZ_CLOCK_GATE_ADC,
704        .ops = &jz_clk_simple_ops,
705    },
706    [6] = {
707        .name = "i2c",
708        .parent = &jz_clk_ext.clk,
709        .gate_bit = JZ_CLOCK_GATE_I2C,
710        .ops = &jz_clk_simple_ops,
711    },
712    [7] = {
713        .name = "aic",
714        .parent = &jz_clk_ext.clk,
715        .gate_bit = JZ_CLOCK_GATE_AIC,
716        .ops = &jz_clk_simple_ops,
717    },
531#define DEFINE_GATED_CLOCK0(_name, _parent, _gate_bit) \
532    struct clk _name = { \
533        .parent = parent, \
534        .gate_bit = _gate_bit, \
535        .ops = jz_clk_simple0_ops, \
536    };
537
538
539static struct clk jz_clk_bch = {
540    .name = "bch",
541    .parent = &jz_clk_ext.clk,
542    .gate_bit = JZ_CLOCK_GATE0_BCH,
543    .ops = &jz_clk_simple0_ops,
718544};
719545
720static struct static_clk jz_clk_rtc = {
721    .clk = {
722        .name = "rtc",
723        .gate_bit = JZ_CLOCK_GATE_RTC,
724        .ops = &jz_clk_static_ops,
725    },
726    .rate = 32768,
546static struct clk jz_clk_emc = {
547    .name = "emc",
548    .parent = &jz_clk_ext.clk,
549    .gate_bit = JZ_CLOCK_GATE0_EMC,
550    .ops = &jz_clk_simple0_ops,
727551};
728552
729int clk_enable(struct clk *clk)
730{
731    if (!clk->ops->enable)
732        return -EINVAL;
553static struct clk jz_clk_ssi0 = {
554    .name = "ssi0",
555    .parent = &jz_clk_ssi.clk,
556    .gate_bit = JZ_CLOCK_GATE0_SSI0,
557    .ops = &jz_clk_simple0_ops,
558};
733559
734    return clk->ops->enable(clk);
735}
736EXPORT_SYMBOL_GPL(clk_enable);
560static struct clk jz_clk_ssi1 = {
561    .name = "ssi1",
562    .parent = &jz_clk_ssi.clk,
563    .gate_bit = JZ_CLOCK_GATE0_SSI1,
564    .ops = &jz_clk_simple0_ops,
565};
737566
738void clk_disable(struct clk *clk)
739{
740    if (clk->ops->disable)
741        clk->ops->disable(clk);
742}
743EXPORT_SYMBOL_GPL(clk_disable);
567static struct clk jz_clk_ssi2 = {
568    .name = "ssi2",
569    .parent = &jz_clk_ssi.clk,
570    .gate_bit = JZ_CLOCK_GATE0_SSI2,
571    .ops = &jz_clk_simple0_ops,
572};
744573
745int clk_is_enabled(struct clk *clk)
746{
747    if (clk->ops->is_enabled)
748        return clk->ops->is_enabled(clk);
574static struct clk jz_clk_msc0 = {
575    .name = "msc0",
576    .parent = &jz_clk_msc.clk,
577    .gate_bit = JZ_CLOCK_GATE0_MSC0,
578    .ops = &jz_clk_simple0_ops,
579};
749580
750    return 1;
751}
581static struct clk jz_clk_msc1 = {
582    .name = "msc1",
583    .parent = &jz_clk_msc.clk,
584    .gate_bit = JZ_CLOCK_GATE0_MSC1,
585    .ops = &jz_clk_simple0_ops,
586};
752587
753unsigned long clk_get_rate(struct clk *clk)
754{
755    if (clk->ops->get_rate)
756        return clk->ops->get_rate(clk);
757    if (clk->parent)
758        return clk_get_rate(clk->parent);
588static struct clk jz_clk_msc2 = {
589    .name = "msc2",
590    .parent = &jz_clk_msc.clk,
591    .gate_bit = JZ_CLOCK_GATE0_MSC2,
592    .ops = &jz_clk_simple0_ops,
593};
759594
760    return -EINVAL;
761}
762EXPORT_SYMBOL_GPL(clk_get_rate);
595static struct clk jz_clk_uart0 = {
596    .name = "uart0",
597    .parent = &jz_clk_ext.clk,
598    .gate_bit = JZ_CLOCK_GATE0_UART0,
599    .ops = &jz_clk_simple0_ops,
600};
763601
764int clk_set_rate(struct clk *clk, unsigned long rate)
765{
766    if (!clk->ops->set_rate)
767        return -EINVAL;
768    return clk->ops->set_rate(clk, rate);
769}
770EXPORT_SYMBOL_GPL(clk_set_rate);
602static struct clk jz_clk_uart1 = {
603    .name = "uart1",
604    .parent = &jz_clk_ext.clk,
605    .gate_bit = JZ_CLOCK_GATE0_UART1,
606    .ops = &jz_clk_simple0_ops,
607};
771608
772long clk_round_rate(struct clk *clk, unsigned long rate)
773{
774    if (clk->ops->round_rate)
775        return clk->ops->round_rate(clk, rate);
609static struct clk jz_clk_uart2 = {
610    .name = "uart2",
611    .parent = &jz_clk_ext.clk,
612    .gate_bit = JZ_CLOCK_GATE0_UART2,
613    .ops = &jz_clk_simple0_ops,
614};
776615
777    return -EINVAL;
778}
779EXPORT_SYMBOL_GPL(clk_round_rate);
616static struct clk jz_clk_uart3 = {
617    .name = "uart3",
618    .parent = &jz_clk_ext.clk,
619    .gate_bit = JZ_CLOCK_GATE0_UART3,
620    .ops = &jz_clk_simple0_ops,
621};
780622
781int clk_set_parent(struct clk *clk, struct clk *parent)
782{
783    int ret;
784    int enabled;
623static struct clk jz_clk_dma = {
624    .name = "dma",
625    .parent = &jz_clk_high_speed_peripheral.clk,
626    .gate_bit = JZ_CLOCK_GATE0_DMAC,
627    .ops = &jz_clk_simple0_ops,
628};
785629
786    if (!clk->ops->set_parent)
787        return -EINVAL;
630static struct clk jz_clk_ipu = {
631    .name = "ipu",
632    .parent = &jz_clk_high_speed_peripheral.clk,
633    .gate_bit = JZ_CLOCK_GATE0_IPU,
634    .ops = &jz_clk_simple0_ops,
635};
788636
789    enabled = clk_is_enabled(clk);
790    if (enabled)
791        clk_disable(clk);
792    ret = clk->ops->set_parent(clk, parent);
793    if (enabled)
794        clk_enable(clk);
637static struct clk jz_clk_adc = {
638    .name = "adc",
639    .parent = &jz_clk_ext.clk,
640    .gate_bit = JZ_CLOCK_GATE0_SADC,
641    .ops = &jz_clk_simple0_ops,
642};
795643
796    jz4740_clock_debugfs_update_parent(clk);
644static struct clk jz_clk_i2c0 = {
645    .name = "i2c0",
646    .parent = &jz_clk_ext.clk,
647    .gate_bit = JZ_CLOCK_GATE0_I2C0,
648    .ops = &jz_clk_simple0_ops,
649};
797650
798    return ret;
799}
800EXPORT_SYMBOL_GPL(clk_set_parent);
651static struct clk jz_clk_i2c1 = {
652    .name = "i2c1",
653    .parent = &jz_clk_ext.clk,
654    .gate_bit = JZ_CLOCK_GATE0_I2C1,
655    .ops = &jz_clk_simple0_ops,
656};
801657
802struct clk *clk_get(struct device *dev, const char *name)
803{
804    struct clk *clk;
658static struct clk jz_clk_aic = {
659    .name = "aic",
660    .parent = &jz_clk_ext.clk,
661    .gate_bit = JZ_CLOCK_GATE0_AIC,
662    .ops = &jz_clk_simple0_ops,
663};
805664
806    list_for_each_entry(clk, &jz_clocks, list) {
807        if (strcmp(clk->name, name) == 0)
808            return clk;
809    }
810    return ERR_PTR(-ENXIO);
811}
812EXPORT_SYMBOL_GPL(clk_get);
665static struct clk jz_clk_ld = {
666    .name = "lcd",
667    .parent = &jz_clk_ext.clk,
668    .gate_bit = JZ_CLOCK_GATE0_AIC,
669    .ops = &jz_clk_simple0_ops,
670};
813671
814void clk_put(struct clk *clk)
815{
816}
817EXPORT_SYMBOL_GPL(clk_put);
672static struct static_clk jz_clk_rtc = {
673    .clk = {
674        .name = "rtc",
675        .gate_bit = JZ47XX_CLK_NOT_GATED,
676        .ops = &jz_clk_static_ops,
677    },
678    .rate = 32768,
679};
818680
819static inline void clk_add(struct clk *clk)
820{
821    list_add_tail(&clk->list, &jz_clocks);
681#define INIT_CLOCK(_dev, _con, _clk) \
682    { .dev_id = _dev, .con_id = _con, .clk = _clk, }
683
684static struct clk_lookup jz4760_clk_table[] = {
685    INIT_CLOCK(NULL, "ext", &jz_clk_ext.clk),
686    INIT_CLOCK(NULL, "pll", &jz_clk_pll),
687    INIT_CLOCK(NULL, "pll half", &jz_clk_pll_half),
688    INIT_CLOCK(NULL, "cclk", &jz_clk_cpu.clk),
689    INIT_CLOCK(NULL, "mclk", &jz_clk_memory.clk),
690    INIT_CLOCK(NULL, "hclk", &jz_clk_high_speed_peripheral.clk),
691    INIT_CLOCK(NULL, "pclk", &jz_clk_low_speed_peripheral.clk),
692    INIT_CLOCK(NULL, "h2clk", &jz_clk_high_speed_peripheral2.clk),
693    INIT_CLOCK(NULL, "sclk", &jz_clk_static_peripheral.clk),
694
695    INIT_CLOCK("jz4750-nand", "bch", &jz_clk_bch),
696    INIT_CLOCK("jz4750-nand", "emc", &jz_clk_emc),
697
698    INIT_CLOCK("jz4740-rtc", "rtc", &jz_clk_rtc.clk),
699    INIT_CLOCK("jz4740-fb", "lcd", &jz_clk_ld),
700    INIT_CLOCK("jz4740-fb", "lcd_pclk", &jz_clk_lcd_pclk.clk),
701    INIT_CLOCK(NULL, "ssi", &jz_clk_ssi.clk),
702    INIT_CLOCK(NULL, "ssi0", &jz_clk_ssi0),
703    INIT_CLOCK(NULL, "ssi1", &jz_clk_ssi1),
704    INIT_CLOCK(NULL, "ssi2", &jz_clk_ssi2),
705
706    INIT_CLOCK(NULL, "i2c0", &jz_clk_i2c0),
707    INIT_CLOCK(NULL, "i2c1", &jz_clk_i2c1),
708
709    INIT_CLOCK("jz4740-i2s", "i2s", &jz_clk_i2s.clk),
710    INIT_CLOCK("jz4740-i2s", "aic", &jz_clk_aic),
711
712    INIT_CLOCK("jz4740-adc", "adc", &jz_clk_adc),
713/* INIT_CLOCK("jz-udc", "udc", &jz_clk_udc),
714    INIT_CLOCK("jz-udc", "udc-phy", &jz_clk_udc_phy),*/
715    INIT_CLOCK(NULL, "msc", &jz_clk_msc.clk),
716    INIT_CLOCK("jz4740-mmc.0", "mmc", &jz_clk_msc0),
717    INIT_CLOCK("jz4740-mmc.1", "mmc", &jz_clk_msc1),
718    INIT_CLOCK("jz4740-mmc.2", "mmc", &jz_clk_msc2),
719    INIT_CLOCK("jz4740-ohci", "uhc", &jz_clk_uhc.clk),
720    INIT_CLOCK("jz4740-ohci", "uhc-ohy", &jz_clk_uhc.clk),
721
722    INIT_CLOCK(NULL, "uart0", &jz_clk_uart0),
723    INIT_CLOCK(NULL, "uart1", &jz_clk_uart1),
724    INIT_CLOCK(NULL, "uart1", &jz_clk_uart2),
725    INIT_CLOCK(NULL, "uart1", &jz_clk_uart3),
726    INIT_CLOCK(NULL, "dma", &jz_clk_dma),
727    INIT_CLOCK(NULL, "ipu", &jz_clk_ipu),
728};
822729
823    jz4740_clock_debugfs_add_clk(clk);
824}
825730
826static void clk_register_clks(void)
731static void __init clk_register_clks(void)
827732{
828    size_t i;
829
830    clk_add(&jz_clk_ext.clk);
831    clk_add(&jz_clk_pll);
832    clk_add(&jz_clk_pll_half);
833    clk_add(&jz_clk_cpu.clk);
834    clk_add(&jz_clk_high_speed_peripheral.clk);
835    clk_add(&jz_clk_low_speed_peripheral.clk);
836    clk_add(&jz_clk_ko);
837    clk_add(&jz_clk_ld);
838    clk_add(&jz_clk_rtc.clk);
839
840    for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
841        clk_add(&jz4740_clock_divided_clks[i].clk);
842
843    for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
844        clk_add(&jz4740_clock_simple_clks[i]);
733    jz47xx_clock_add_table(jz4760_clk_table, ARRAY_SIZE(jz4760_clk_table));
845734}
846735
847void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
736void jz47xx_clock_set_wait_mode(enum jz47xx_wait_mode mode)
848737{
849738    switch (mode) {
850    case JZ4740_WAIT_MODE_IDLE:
739    case JZ47XX_WAIT_MODE_IDLE:
851740        jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
852741        break;
853    case JZ4740_WAIT_MODE_SLEEP:
742    case JZ47XX_WAIT_MODE_SLEEP:
854743        jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
855744        break;
856745    }
857746}
858747
859void jz4740_clock_udc_disable_auto_suspend(void)
860{
861    jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
862}
863EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
864
865void jz4740_clock_udc_enable_auto_suspend(void)
748void jz47xx_clock_suspend(void)
866749{
867    jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
868}
869EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
870
871void jz4740_clock_suspend(void)
872{
873    jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
874        JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
875
876750    jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
877751}
878752
879void jz4740_clock_resume(void)
753void jz47xx_clock_resume(void)
880754{
881755    uint32_t pll;
882756
...... 
885759    do {
886760        pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
887761    } while (!(pll & JZ_CLOCK_PLL_STABLE));
888
889    jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
890        JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
891762}
892763
893static int jz4740_clock_init(void)
764static int __init jz4760_clock_init(void)
894765{
895766    uint32_t val;
896767
...... 
900771
901772    spin_lock_init(&jz_clock_lock);
902773
903    jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
904    jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
905
906    val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
774    jz_clk_ext.rate = jz47xx_clock_bdata.ext_rate;
775    jz_clk_rtc.rate = jz47xx_clock_bdata.rtc_rate;
907776
908    if (val & JZ_CLOCK_SPI_SRC_PLL)
909        jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
777    val = jz_clk_reg_read(JZ_REG_CLOCK_I2S);
778    if (val & JZ_CLOCK_I2S_SRC_PLL) {
779        if (val & JZ_CLOCK_I2S_SRC_PLL1)
780            jz_clk_i2s.clk.parent = &jz_clk_pll_half;
781        else
782            jz_clk_i2s.clk.parent = &jz_clk_pll_half;
783    }
910784
911    val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
785    val = jz_clk_reg_read(JZ_REG_CLOCK_SSI);
786    if (val & JZ_CLOCK_SSI_SRC_PLL0)
787        jz_clk_ssi.clk.parent = &jz_clk_pll_half;
912788
913    if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
914        jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
789    val = jz_clk_reg_read(JZ_REG_CLOCK_MSC);
790    if (!(val & JZ_CLOCK_MSC_SRC_PLL0))
791        jz_clk_msc.clk.parent = &jz_clk_pll_half;
915792
916    if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
917        jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
793    clk_set_rate(&jz_clk_msc.clk, 12000000);
918794
919795    jz4740_clock_debugfs_init();
920796
797    jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
798            JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC);
799
800
921801    clk_register_clks();
802    printk("register clks\n");
803
922804
923805    return 0;
924806}
925arch_initcall(jz4740_clock_init);
807arch_initcall(jz4760_clock_init);

Archive Download the corresponding diff file



interactive