]> Pileus Git - ~andy/linux/blob - drivers/clk/socfpga/clk.c
81dd31a686df9e467b7c111f9c808ee568139551
[~andy/linux] / drivers / clk / socfpga / clk.c
1 /*
2  *  Copyright 2011-2012 Calxeda, Inc.
3  *  Copyright (C) 2012-2013 Altera Corporation <www.altera.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * Based from clk-highbank.c
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 #include <linux/clk.h>
21 #include <linux/clkdev.h>
22 #include <linux/clk-provider.h>
23 #include <linux/io.h>
24 #include <linux/of.h>
25
26 /* Clock Manager offsets */
27 #define CLKMGR_CTRL     0x0
28 #define CLKMGR_BYPASS   0x4
29 #define CLKMGR_L4SRC    0x70
30 #define CLKMGR_PERPLL_SRC       0xAC
31
32 /* Clock bypass bits */
33 #define MAINPLL_BYPASS          (1<<0)
34 #define SDRAMPLL_BYPASS         (1<<1)
35 #define SDRAMPLL_SRC_BYPASS     (1<<2)
36 #define PERPLL_BYPASS           (1<<3)
37 #define PERPLL_SRC_BYPASS       (1<<4)
38
39 #define SOCFPGA_PLL_BG_PWRDWN           0
40 #define SOCFPGA_PLL_EXT_ENA             1
41 #define SOCFPGA_PLL_PWR_DOWN            2
42 #define SOCFPGA_PLL_DIVF_MASK           0x0000FFF8
43 #define SOCFPGA_PLL_DIVF_SHIFT  3
44 #define SOCFPGA_PLL_DIVQ_MASK           0x003F0000
45 #define SOCFPGA_PLL_DIVQ_SHIFT  16
46 #define SOCFGPA_MAX_PARENTS     3
47
48 #define SOCFPGA_L4_MP_CLK               "l4_mp_clk"
49 #define SOCFPGA_L4_SP_CLK               "l4_sp_clk"
50 #define SOCFPGA_NAND_CLK                "nand_clk"
51 #define SOCFPGA_NAND_X_CLK              "nand_x_clk"
52 #define SOCFPGA_MMC_CLK                 "sdmmc_clk"
53 #define SOCFPGA_DB_CLK                  "gpio_db_clk"
54
55 #define div_mask(width) ((1 << (width)) - 1)
56 #define streq(a, b) (strcmp((a), (b)) == 0)
57
58 extern void __iomem *clk_mgr_base_addr;
59
60 struct socfpga_clk {
61         struct clk_gate hw;
62         char *parent_name;
63         char *clk_name;
64         u32 fixed_div;
65         void __iomem *div_reg;
66         u32 width;      /* only valid if div_reg != 0 */
67         u32 shift;      /* only valid if div_reg != 0 */
68 };
69 #define to_socfpga_clk(p) container_of(p, struct socfpga_clk, hw.hw)
70
71 static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk,
72                                          unsigned long parent_rate)
73 {
74         struct socfpga_clk *socfpgaclk = to_socfpga_clk(hwclk);
75         unsigned long divf, divq, vco_freq, reg;
76         unsigned long bypass;
77
78         reg = readl(socfpgaclk->hw.reg);
79         bypass = readl(clk_mgr_base_addr + CLKMGR_BYPASS);
80         if (bypass & MAINPLL_BYPASS)
81                 return parent_rate;
82
83         divf = (reg & SOCFPGA_PLL_DIVF_MASK) >> SOCFPGA_PLL_DIVF_SHIFT;
84         divq = (reg & SOCFPGA_PLL_DIVQ_MASK) >> SOCFPGA_PLL_DIVQ_SHIFT;
85         vco_freq = parent_rate * (divf + 1);
86         return vco_freq / (1 + divq);
87 }
88
89
90 static struct clk_ops clk_pll_ops = {
91         .recalc_rate = clk_pll_recalc_rate,
92 };
93
94 static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk,
95                                              unsigned long parent_rate)
96 {
97         struct socfpga_clk *socfpgaclk = to_socfpga_clk(hwclk);
98         u32 div;
99
100         if (socfpgaclk->fixed_div)
101                 div = socfpgaclk->fixed_div;
102         else
103                 div = ((readl(socfpgaclk->hw.reg) & 0x1ff) + 1);
104
105         return parent_rate / div;
106 }
107
108 static const struct clk_ops periclk_ops = {
109         .recalc_rate = clk_periclk_recalc_rate,
110 };
111
112 static __init struct clk *socfpga_clk_init(struct device_node *node,
113         const struct clk_ops *ops)
114 {
115         u32 reg;
116         struct clk *clk;
117         struct socfpga_clk *socfpga_clk;
118         const char *clk_name = node->name;
119         const char *parent_name;
120         struct clk_init_data init;
121         int rc;
122         u32 fixed_div;
123
124         rc = of_property_read_u32(node, "reg", &reg);
125         if (WARN_ON(rc))
126                 return NULL;
127
128         socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
129         if (WARN_ON(!socfpga_clk))
130                 return NULL;
131
132         socfpga_clk->hw.reg = clk_mgr_base_addr + reg;
133
134         rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
135         if (rc)
136                 socfpga_clk->fixed_div = 0;
137         else
138                 socfpga_clk->fixed_div = fixed_div;
139
140         of_property_read_string(node, "clock-output-names", &clk_name);
141
142         init.name = clk_name;
143         init.ops = ops;
144         init.flags = 0;
145         parent_name = of_clk_get_parent_name(node, 0);
146         init.parent_names = &parent_name;
147         init.num_parents = 1;
148
149         socfpga_clk->hw.hw.init = &init;
150
151         if (streq(clk_name, "main_pll") ||
152                 streq(clk_name, "periph_pll") ||
153                 streq(clk_name, "sdram_pll")) {
154                 socfpga_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
155                 clk_pll_ops.enable = clk_gate_ops.enable;
156                 clk_pll_ops.disable = clk_gate_ops.disable;
157         }
158
159         clk = clk_register(NULL, &socfpga_clk->hw.hw);
160         if (WARN_ON(IS_ERR(clk))) {
161                 kfree(socfpga_clk);
162                 return NULL;
163         }
164         rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
165         return clk;
166 }
167
168 static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
169 {
170         u32 l4_src;
171         u32 perpll_src;
172
173         if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
174                 l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
175                 return l4_src &= 0x1;
176         }
177         if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
178                 l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
179                 return !!(l4_src & 2);
180         }
181
182         perpll_src = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
183         if (streq(hwclk->init->name, SOCFPGA_MMC_CLK))
184                 return perpll_src &= 0x3;
185         if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
186                         streq(hwclk->init->name, SOCFPGA_NAND_X_CLK))
187                         return (perpll_src >> 2) & 3;
188
189         /* QSPI clock */
190         return (perpll_src >> 4) & 3;
191
192 }
193
194 static int socfpga_clk_set_parent(struct clk_hw *hwclk, u8 parent)
195 {
196         u32 src_reg;
197
198         if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
199                 src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
200                 src_reg &= ~0x1;
201                 src_reg |= parent;
202                 writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
203         } else if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
204                 src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
205                 src_reg &= ~0x2;
206                 src_reg |= (parent << 1);
207                 writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
208         } else {
209                 src_reg = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
210                 if (streq(hwclk->init->name, SOCFPGA_MMC_CLK)) {
211                         src_reg &= ~0x3;
212                         src_reg |= parent;
213                 } else if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
214                         streq(hwclk->init->name, SOCFPGA_NAND_X_CLK)) {
215                         src_reg &= ~0xC;
216                         src_reg |= (parent << 2);
217                 } else {/* QSPI clock */
218                         src_reg &= ~0x30;
219                         src_reg |= (parent << 4);
220                 }
221                 writel(src_reg, clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
222         }
223
224         return 0;
225 }
226
227 static unsigned long socfpga_clk_recalc_rate(struct clk_hw *hwclk,
228         unsigned long parent_rate)
229 {
230         struct socfpga_clk *socfpgaclk = to_socfpga_clk(hwclk);
231         u32 div = 1, val;
232
233         if (socfpgaclk->fixed_div)
234                 div = socfpgaclk->fixed_div;
235         else if (socfpgaclk->div_reg) {
236                 val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
237                 val &= div_mask(socfpgaclk->width);
238                 if (streq(hwclk->init->name, SOCFPGA_DB_CLK))
239                         div = val + 1;
240                 else
241                         div = (1 << val);
242         }
243
244         return parent_rate / div;
245 }
246
247 static struct clk_ops gateclk_ops = {
248         .recalc_rate = socfpga_clk_recalc_rate,
249         .get_parent = socfpga_clk_get_parent,
250         .set_parent = socfpga_clk_set_parent,
251 };
252
253 static void __init socfpga_gate_clk_init(struct device_node *node,
254         const struct clk_ops *ops)
255 {
256         u32 clk_gate[2];
257         u32 div_reg[3];
258         u32 fixed_div;
259         struct clk *clk;
260         struct socfpga_clk *socfpga_clk;
261         const char *clk_name = node->name;
262         const char *parent_name[SOCFGPA_MAX_PARENTS];
263         struct clk_init_data init;
264         int rc;
265         int i = 0;
266
267         socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
268         if (WARN_ON(!socfpga_clk))
269                 return;
270
271         rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
272         if (rc)
273                 clk_gate[0] = 0;
274
275         if (clk_gate[0]) {
276                 socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0];
277                 socfpga_clk->hw.bit_idx = clk_gate[1];
278
279                 gateclk_ops.enable = clk_gate_ops.enable;
280                 gateclk_ops.disable = clk_gate_ops.disable;
281         }
282
283         rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
284         if (rc)
285                 socfpga_clk->fixed_div = 0;
286         else
287                 socfpga_clk->fixed_div = fixed_div;
288
289         rc = of_property_read_u32_array(node, "div-reg", div_reg, 3);
290         if (!rc) {
291                 socfpga_clk->div_reg = clk_mgr_base_addr + div_reg[0];
292                 socfpga_clk->shift = div_reg[1];
293                 socfpga_clk->width = div_reg[2];
294         } else {
295                 socfpga_clk->div_reg = 0;
296         }
297
298         of_property_read_string(node, "clock-output-names", &clk_name);
299
300         init.name = clk_name;
301         init.ops = ops;
302         init.flags = 0;
303         while (i < SOCFGPA_MAX_PARENTS && (parent_name[i] =
304                         of_clk_get_parent_name(node, i)) != NULL)
305                 i++;
306
307         init.parent_names = parent_name;
308         init.num_parents = i;
309         socfpga_clk->hw.hw.init = &init;
310
311         clk = clk_register(NULL, &socfpga_clk->hw.hw);
312         if (WARN_ON(IS_ERR(clk))) {
313                 kfree(socfpga_clk);
314                 return;
315         }
316         rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
317         if (WARN_ON(rc))
318                 return;
319 }
320
321 static void __init socfpga_pll_init(struct device_node *node)
322 {
323         socfpga_clk_init(node, &clk_pll_ops);
324 }
325 CLK_OF_DECLARE(socfpga_pll, "altr,socfpga-pll-clock", socfpga_pll_init);
326
327 static void __init socfpga_periph_init(struct device_node *node)
328 {
329         socfpga_clk_init(node, &periclk_ops);
330 }
331 CLK_OF_DECLARE(socfpga_periph, "altr,socfpga-perip-clk", socfpga_periph_init);
332
333 static void __init socfpga_gate_init(struct device_node *node)
334 {
335         socfpga_gate_clk_init(node, &gateclk_ops);
336 }
337 CLK_OF_DECLARE(socfpga_gate, "altr,socfpga-gate-clk", socfpga_gate_init);
338
339 void __init socfpga_init_clocks(void)
340 {
341         struct clk *clk;
342         int ret;
343
344         clk = clk_register_fixed_factor(NULL, "smp_twd", "mpuclk", 0, 1, 4);
345         ret = clk_register_clkdev(clk, NULL, "smp_twd");
346         if (ret)
347                 pr_err("smp_twd alias not registered\n");
348 }