dm: core: Require users of devres to include the header
[platform/kernel/u-boot.git] / drivers / clk / altera / clk-arria10.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2018 Marek Vasut <marex@denx.de>
4  */
5
6 #include <common.h>
7 #include <asm/io.h>
8 #include <clk-uclass.h>
9 #include <dm.h>
10 #include <dm/devres.h>
11 #include <dm/lists.h>
12 #include <dm/util.h>
13
14 #include <asm/arch/clock_manager.h>
15
16 enum socfpga_a10_clk_type {
17         SOCFPGA_A10_CLK_MAIN_PLL,
18         SOCFPGA_A10_CLK_PER_PLL,
19         SOCFPGA_A10_CLK_PERIP_CLK,
20         SOCFPGA_A10_CLK_GATE_CLK,
21         SOCFPGA_A10_CLK_UNKNOWN_CLK,
22 };
23
24 struct socfpga_a10_clk_platdata {
25         enum socfpga_a10_clk_type type;
26         struct clk_bulk clks;
27         u32             regs;
28         /* Fixed divider */
29         u16             fix_div;
30         /* Control register */
31         u16             ctl_reg;
32         /* Divider register */
33         u16             div_reg;
34         u8              div_len;
35         u8              div_off;
36         /* Clock gating register */
37         u16             gate_reg;
38         u8              gate_bit;
39 };
40
41 static int socfpga_a10_clk_get_upstream(struct clk *clk, struct clk **upclk)
42 {
43         struct socfpga_a10_clk_platdata *plat = dev_get_platdata(clk->dev);
44         u32 reg, maxval;
45
46         if (plat->clks.count == 0)
47                 return 0;
48
49         if (plat->clks.count == 1) {
50                 *upclk = &plat->clks.clks[0];
51                 return 0;
52         }
53
54         if (!plat->ctl_reg) {
55                 dev_err(clk->dev, "Invalid control register\n");
56                 return -EINVAL;
57         }
58
59         reg = readl(plat->regs + plat->ctl_reg);
60
61         /* Assume PLLs are ON for now */
62         if (plat->type == SOCFPGA_A10_CLK_MAIN_PLL) {
63                 reg = (reg >> 8) & 0x3;
64                 maxval = 2;
65         } else if (plat->type == SOCFPGA_A10_CLK_PER_PLL) {
66                 reg = (reg >> 8) & 0x3;
67                 maxval = 3;
68         } else {
69                 reg = (reg >> 16) & 0x7;
70                 maxval = 4;
71         }
72
73         if (reg > maxval) {
74                 dev_err(clk->dev, "Invalid clock source\n");
75                 return -EINVAL;
76         }
77
78         *upclk = &plat->clks.clks[reg];
79         return 0;
80 }
81
82 static int socfpga_a10_clk_endisable(struct clk *clk, bool enable)
83 {
84         struct socfpga_a10_clk_platdata *plat = dev_get_platdata(clk->dev);
85         struct clk *upclk = NULL;
86         int ret;
87
88         if (!enable && plat->gate_reg)
89                 clrbits_le32(plat->regs + plat->gate_reg, BIT(plat->gate_bit));
90
91         ret = socfpga_a10_clk_get_upstream(clk, &upclk);
92         if (ret)
93                 return ret;
94
95         if (upclk) {
96                 if (enable)
97                         clk_enable(upclk);
98                 else
99                         clk_disable(upclk);
100         }
101
102         if (enable && plat->gate_reg)
103                 setbits_le32(plat->regs + plat->gate_reg, BIT(plat->gate_bit));
104
105         return 0;
106 }
107
108 static int socfpga_a10_clk_enable(struct clk *clk)
109 {
110         return socfpga_a10_clk_endisable(clk, true);
111 }
112
113 static int socfpga_a10_clk_disable(struct clk *clk)
114 {
115         return socfpga_a10_clk_endisable(clk, false);
116 }
117
118 static ulong socfpga_a10_clk_get_rate(struct clk *clk)
119 {
120         struct socfpga_a10_clk_platdata *plat = dev_get_platdata(clk->dev);
121         struct clk *upclk = NULL;
122         ulong rate = 0, reg, numer, denom;
123         int ret;
124
125         ret = socfpga_a10_clk_get_upstream(clk, &upclk);
126         if (ret || !upclk)
127                 return 0;
128
129         rate = clk_get_rate(upclk);
130
131         if (plat->type == SOCFPGA_A10_CLK_MAIN_PLL) {
132                 reg = readl(plat->regs + plat->ctl_reg + 4);    /* VCO1 */
133                 numer = reg & CLKMGR_MAINPLL_VCO1_NUMER_MSK;
134                 denom = (reg >> CLKMGR_MAINPLL_VCO1_DENOM_LSB) &
135                         CLKMGR_MAINPLL_VCO1_DENOM_MSK;
136
137                 rate /= denom + 1;
138                 rate *= numer + 1;
139         } else if (plat->type == SOCFPGA_A10_CLK_PER_PLL) {
140                 reg = readl(plat->regs + plat->ctl_reg + 4);    /* VCO1 */
141                 numer = reg & CLKMGR_PERPLL_VCO1_NUMER_MSK;
142                 denom = (reg >> CLKMGR_PERPLL_VCO1_DENOM_LSB) &
143                         CLKMGR_PERPLL_VCO1_DENOM_MSK;
144
145                 rate /= denom + 1;
146                 rate *= numer + 1;
147         } else {
148                 rate /= plat->fix_div;
149
150                 if (plat->fix_div == 1 && plat->ctl_reg) {
151                         reg = readl(plat->regs + plat->ctl_reg);
152                         reg &= 0x7ff;
153                         rate /= reg + 1;
154                 }
155
156                 if (plat->div_reg) {
157                         reg = readl(plat->regs + plat->div_reg);
158                         reg >>= plat->div_off;
159                         reg &= (1 << plat->div_len) - 1;
160                         if (plat->type == SOCFPGA_A10_CLK_PERIP_CLK)
161                                 rate /= reg + 1;
162                         if (plat->type == SOCFPGA_A10_CLK_GATE_CLK)
163                                 rate /= 1 << reg;
164                 }
165         }
166
167         return rate;
168 }
169
170 static struct clk_ops socfpga_a10_clk_ops = {
171         .enable         = socfpga_a10_clk_enable,
172         .disable        = socfpga_a10_clk_disable,
173         .get_rate       = socfpga_a10_clk_get_rate,
174 };
175
176 /*
177  * This workaround tries to fix the massively broken generated "handoff" DT,
178  * which contains duplicate clock nodes without any connection to the clock
179  * manager DT node. Yet, those "handoff" DT nodes contain configuration of
180  * the fixed input clock of the Arria10 which are missing from the base DT
181  * for Arria10.
182  *
183  * This workaround sets up upstream clock for the fixed input clocks of the
184  * A10 described in the base DT such that they map to the fixed clock from
185  * the "handoff" DT. This does not fully match how the clock look on the
186  * A10, but it is the least intrusive way to fix this mess.
187  */
188 static void socfpga_a10_handoff_workaround(struct udevice *dev)
189 {
190         struct socfpga_a10_clk_platdata *plat = dev_get_platdata(dev);
191         const void *fdt = gd->fdt_blob;
192         struct clk_bulk *bulk = &plat->clks;
193         int i, ret, offset = dev_of_offset(dev);
194         static const char * const socfpga_a10_fixedclk_map[] = {
195                 "osc1", "altera_arria10_hps_eosc1",
196                 "cb_intosc_ls_clk", "altera_arria10_hps_cb_intosc_ls",
197                 "f2s_free_clk", "altera_arria10_hps_f2h_free",
198         };
199
200         if (fdt_node_check_compatible(fdt, offset, "fixed-clock"))
201                 return;
202
203         for (i = 0; i < ARRAY_SIZE(socfpga_a10_fixedclk_map); i += 2)
204                 if (!strcmp(dev->name, socfpga_a10_fixedclk_map[i]))
205                         break;
206
207         if (i == ARRAY_SIZE(socfpga_a10_fixedclk_map))
208                 return;
209
210         ret = uclass_get_device_by_name(UCLASS_CLK,
211                                         socfpga_a10_fixedclk_map[i + 1], &dev);
212         if (ret)
213                 return;
214
215         bulk->count = 1;
216         bulk->clks = devm_kcalloc(dev, bulk->count,
217                                   sizeof(struct clk), GFP_KERNEL);
218         if (!bulk->clks)
219                 return;
220
221         ret = clk_request(dev, &bulk->clks[0]);
222         if (ret)
223                 free(bulk->clks);
224 }
225
226 static int socfpga_a10_clk_bind(struct udevice *dev)
227 {
228         const void *fdt = gd->fdt_blob;
229         int offset = dev_of_offset(dev);
230         bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
231         const char *name;
232         int ret;
233
234         for (offset = fdt_first_subnode(fdt, offset);
235              offset > 0;
236              offset = fdt_next_subnode(fdt, offset)) {
237                 name = fdt_get_name(fdt, offset, NULL);
238                 if (!name)
239                         return -EINVAL;
240
241                 if (!strcmp(name, "clocks")) {
242                         offset = fdt_first_subnode(fdt, offset);
243                         name = fdt_get_name(fdt, offset, NULL);
244                         if (!name)
245                                 return -EINVAL;
246                 }
247
248                 /* Filter out supported sub-clock */
249                 if (fdt_node_check_compatible(fdt, offset,
250                                               "altr,socfpga-a10-pll-clock") &&
251                     fdt_node_check_compatible(fdt, offset,
252                                               "altr,socfpga-a10-perip-clk") &&
253                     fdt_node_check_compatible(fdt, offset,
254                                               "altr,socfpga-a10-gate-clk") &&
255                     fdt_node_check_compatible(fdt, offset, "fixed-clock"))
256                         continue;
257
258                 if (pre_reloc_only &&
259                     !dm_ofnode_pre_reloc(offset_to_ofnode(offset)))
260                         continue;
261
262                 ret = device_bind_driver_to_node(dev, "clk-a10", name,
263                                                  offset_to_ofnode(offset),
264                                                  NULL);
265                 if (ret)
266                         return ret;
267         }
268
269         return 0;
270 }
271
272 static int socfpga_a10_clk_probe(struct udevice *dev)
273 {
274         struct socfpga_a10_clk_platdata *plat = dev_get_platdata(dev);
275         const void *fdt = gd->fdt_blob;
276         int offset = dev_of_offset(dev);
277
278         clk_get_bulk(dev, &plat->clks);
279
280         socfpga_a10_handoff_workaround(dev);
281
282         if (!fdt_node_check_compatible(fdt, offset,
283                                        "altr,socfpga-a10-pll-clock")) {
284                 /* Main PLL has 3 upstream clock */
285                 if (plat->clks.count == 3)
286                         plat->type = SOCFPGA_A10_CLK_MAIN_PLL;
287                 else
288                         plat->type = SOCFPGA_A10_CLK_PER_PLL;
289         } else if (!fdt_node_check_compatible(fdt, offset,
290                                               "altr,socfpga-a10-perip-clk")) {
291                 plat->type = SOCFPGA_A10_CLK_PERIP_CLK;
292         } else if (!fdt_node_check_compatible(fdt, offset,
293                                               "altr,socfpga-a10-gate-clk")) {
294                 plat->type = SOCFPGA_A10_CLK_GATE_CLK;
295         } else {
296                 plat->type = SOCFPGA_A10_CLK_UNKNOWN_CLK;
297         }
298
299         return 0;
300 }
301
302 static int socfpga_a10_ofdata_to_platdata(struct udevice *dev)
303 {
304         struct socfpga_a10_clk_platdata *plat = dev_get_platdata(dev);
305         struct socfpga_a10_clk_platdata *pplat;
306         struct udevice *pdev;
307         const void *fdt = gd->fdt_blob;
308         unsigned int divreg[3], gatereg[2];
309         int ret, offset = dev_of_offset(dev);
310         u32 regs;
311
312         regs = dev_read_u32_default(dev, "reg", 0x0);
313
314         if (!fdt_node_check_compatible(fdt, offset, "altr,clk-mgr")) {
315                 plat->regs = devfdt_get_addr(dev);
316         } else {
317                 pdev = dev_get_parent(dev);
318                 if (!pdev)
319                         return -ENODEV;
320
321                 pplat = dev_get_platdata(pdev);
322                 if (!pplat)
323                         return -EINVAL;
324
325                 plat->ctl_reg = regs;
326                 plat->regs = pplat->regs;
327         }
328
329         plat->type = SOCFPGA_A10_CLK_UNKNOWN_CLK;
330
331         plat->fix_div = dev_read_u32_default(dev, "fixed-divider", 1);
332
333         ret = dev_read_u32_array(dev, "div-reg", divreg, ARRAY_SIZE(divreg));
334         if (!ret) {
335                 plat->div_reg = divreg[0];
336                 plat->div_len = divreg[2];
337                 plat->div_off = divreg[1];
338         }
339
340         ret = dev_read_u32_array(dev, "clk-gate", gatereg, ARRAY_SIZE(gatereg));
341         if (!ret) {
342                 plat->gate_reg = gatereg[0];
343                 plat->gate_bit = gatereg[1];
344         }
345
346         return 0;
347 }
348
349 static const struct udevice_id socfpga_a10_clk_match[] = {
350         { .compatible = "altr,clk-mgr" },
351         {}
352 };
353
354 U_BOOT_DRIVER(socfpga_a10_clk) = {
355         .name           = "clk-a10",
356         .id             = UCLASS_CLK,
357         .of_match       = socfpga_a10_clk_match,
358         .ops            = &socfpga_a10_clk_ops,
359         .bind           = socfpga_a10_clk_bind,
360         .probe          = socfpga_a10_clk_probe,
361         .ofdata_to_platdata = socfpga_a10_ofdata_to_platdata,
362
363         .platdata_auto_alloc_size = sizeof(struct socfpga_a10_clk_platdata),
364 };