diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2013-04-05 00:21:39 -0400 |
---|---|---|
committer | Simon Horman <horms+renesas@verge.net.au> | 2013-06-07 01:24:45 -0400 |
commit | 0c3091ad45ac975244a7c0570e10b645743bb01c (patch) | |
tree | ca54c43dd78987b2c95be0c893202a4fb5003ed0 | |
parent | 5e634d98635a135016d77e03de2cecbaba8d9d56 (diff) |
ARM: shmobile: r8a73a4: add pll clocks
PLL clocks are basis clock for other clock.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
-rw-r--r-- | arch/arm/mach-shmobile/clock-r8a73a4.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c index 42942b4359dc..2be592f6dbc0 100644 --- a/arch/arm/mach-shmobile/clock-r8a73a4.c +++ b/arch/arm/mach-shmobile/clock-r8a73a4.c | |||
@@ -33,6 +33,14 @@ | |||
33 | #define SMSTPCR5 0xe6150144 | 33 | #define SMSTPCR5 0xe6150144 |
34 | 34 | ||
35 | #define CKSCR 0xE61500C0 | 35 | #define CKSCR 0xE61500C0 |
36 | #define PLLECR 0xE61500D0 | ||
37 | #define PLL1CR 0xE6150028 | ||
38 | #define PLL2CR 0xE615002C | ||
39 | #define PLL2SCR 0xE61501F4 | ||
40 | #define PLL2HCR 0xE61501E4 | ||
41 | |||
42 | |||
43 | #define CPG_MAP(o) ((o - CPG_BASE) + cpg_mapping.base) | ||
36 | 44 | ||
37 | static struct clk_mapping cpg_mapping = { | 45 | static struct clk_mapping cpg_mapping = { |
38 | .phys = CPG_BASE, | 46 | .phys = CPG_BASE, |
@@ -71,6 +79,86 @@ SH_FIXED_RATIO_CLK(extal1_div2_clk, extal1_clk, div2); | |||
71 | SH_FIXED_RATIO_CLK(extal2_div2_clk, extal2_clk, div2); | 79 | SH_FIXED_RATIO_CLK(extal2_div2_clk, extal2_clk, div2); |
72 | SH_FIXED_RATIO_CLK(extal2_div4_clk, extal2_clk, div4); | 80 | SH_FIXED_RATIO_CLK(extal2_div4_clk, extal2_clk, div4); |
73 | 81 | ||
82 | /* | ||
83 | * PLL clocks | ||
84 | */ | ||
85 | static struct clk *pll_parent_main[] = { | ||
86 | [0] = &main_clk, | ||
87 | [1] = &main_div2_clk | ||
88 | }; | ||
89 | |||
90 | static struct clk *pll_parent_main_extal[8] = { | ||
91 | [0] = &main_div2_clk, | ||
92 | [1] = &extal2_div2_clk, | ||
93 | [3] = &extal2_div4_clk, | ||
94 | [4] = &main_clk, | ||
95 | [5] = &extal2_clk, | ||
96 | }; | ||
97 | |||
98 | static unsigned long pll_recalc(struct clk *clk) | ||
99 | { | ||
100 | unsigned long mult = 1; | ||
101 | |||
102 | if (ioread32(CPG_MAP(PLLECR)) & (1 << clk->enable_bit)) | ||
103 | mult = (((ioread32(clk->mapped_reg) >> 24) & 0x7f) + 1); | ||
104 | |||
105 | return clk->parent->rate * mult; | ||
106 | } | ||
107 | |||
108 | static int pll_set_parent(struct clk *clk, struct clk *parent) | ||
109 | { | ||
110 | u32 val; | ||
111 | int i, ret; | ||
112 | |||
113 | if (!clk->parent_table || !clk->parent_num) | ||
114 | return -EINVAL; | ||
115 | |||
116 | /* Search the parent */ | ||
117 | for (i = 0; i < clk->parent_num; i++) | ||
118 | if (clk->parent_table[i] == parent) | ||
119 | break; | ||
120 | |||
121 | if (i == clk->parent_num) | ||
122 | return -ENODEV; | ||
123 | |||
124 | ret = clk_reparent(clk, parent); | ||
125 | if (ret < 0) | ||
126 | return ret; | ||
127 | |||
128 | val = ioread32(clk->mapped_reg) & | ||
129 | ~(((1 << clk->src_width) - 1) << clk->src_shift); | ||
130 | |||
131 | iowrite32(val | i << clk->src_shift, clk->mapped_reg); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static struct sh_clk_ops pll_clk_ops = { | ||
137 | .recalc = pll_recalc, | ||
138 | .set_parent = pll_set_parent, | ||
139 | }; | ||
140 | |||
141 | #define PLL_CLOCK(name, p, pt, w, s, reg, e) \ | ||
142 | static struct clk name = { \ | ||
143 | .ops = &pll_clk_ops, \ | ||
144 | .flags = CLK_ENABLE_ON_INIT, \ | ||
145 | .parent = p, \ | ||
146 | .parent_table = pt, \ | ||
147 | .parent_num = ARRAY_SIZE(pt), \ | ||
148 | .src_width = w, \ | ||
149 | .src_shift = s, \ | ||
150 | .enable_reg = (void __iomem *)reg, \ | ||
151 | .enable_bit = e, \ | ||
152 | .mapping = &cpg_mapping, \ | ||
153 | } | ||
154 | |||
155 | PLL_CLOCK(pll1_clk, &main_clk, pll_parent_main, 1, 7, PLL1CR, 1); | ||
156 | PLL_CLOCK(pll2_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2CR, 2); | ||
157 | PLL_CLOCK(pll2s_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2SCR, 4); | ||
158 | PLL_CLOCK(pll2h_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2HCR, 5); | ||
159 | |||
160 | SH_FIXED_RATIO_CLK(pll1_div2_clk, pll1_clk, div2); | ||
161 | |||
74 | static struct clk *main_clks[] = { | 162 | static struct clk *main_clks[] = { |
75 | &extalr_clk, | 163 | &extalr_clk, |
76 | &extal1_clk, | 164 | &extal1_clk, |
@@ -80,6 +168,11 @@ static struct clk *main_clks[] = { | |||
80 | &extal2_div4_clk, | 168 | &extal2_div4_clk, |
81 | &main_clk, | 169 | &main_clk, |
82 | &main_div2_clk, | 170 | &main_div2_clk, |
171 | &pll1_clk, | ||
172 | &pll1_div2_clk, | ||
173 | &pll2_clk, | ||
174 | &pll2s_clk, | ||
175 | &pll2h_clk, | ||
83 | }; | 176 | }; |
84 | 177 | ||
85 | enum { | 178 | enum { |
@@ -106,6 +199,14 @@ static struct clk_lookup lookups[] = { | |||
106 | CLKDEV_CON_ID("extal2_div2", &extal2_div2_clk), | 199 | CLKDEV_CON_ID("extal2_div2", &extal2_div2_clk), |
107 | CLKDEV_CON_ID("extal2_div4", &extal2_div4_clk), | 200 | CLKDEV_CON_ID("extal2_div4", &extal2_div4_clk), |
108 | 201 | ||
202 | /* pll clock */ | ||
203 | CLKDEV_CON_ID("pll1", &pll1_clk), | ||
204 | CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk), | ||
205 | CLKDEV_CON_ID("pll2", &pll2_clk), | ||
206 | CLKDEV_CON_ID("pll2s", &pll2s_clk), | ||
207 | CLKDEV_CON_ID("pll2h", &pll2h_clk), | ||
208 | |||
209 | /* MSTP */ | ||
109 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), | 210 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), |
110 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), | 211 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), |
111 | CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), | 212 | CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), |