common: Drop linux/delay.h from common header
[oweals/u-boot.git] / drivers / clk / meson / g12a.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2018 - Beniamino Galvani <b.galvani@gmail.com>
4  * (C) Copyright 2018 - BayLibre, SAS
5  * Author: Neil Armstrong <narmstrong@baylibre.com>
6  */
7
8 #include <common.h>
9 #include <log.h>
10 #include <asm/arch/clock-g12a.h>
11 #include <asm/io.h>
12 #include <clk-uclass.h>
13 #include <dm.h>
14 #include <regmap.h>
15 #include <syscon.h>
16 #include <div64.h>
17 #include <dt-bindings/clock/g12a-clkc.h>
18 #include <linux/delay.h>
19 #include <linux/err.h>
20 #include <linux/kernel.h>
21 #include "clk_meson.h"
22
23 /* This driver support only basic clock tree operations :
24  * - Can calculate clock frequency on a limited tree
25  * - Can Read muxes and basic dividers (0-based only)
26  * - Can enable/disable gates with limited propagation
27  * - Can reparent without propagation, only on muxes
28  * - Can set rates without reparenting
29  * This driver is adapted to what is actually supported by U-Boot
30  */
31
32 /* Only the clocks ids we don't want to expose, such as the internal muxes
33  * and dividers of composite clocks, will remain defined here.
34  */
35 #define CLKID_MPEG_SEL                          8
36 #define CLKID_MPEG_DIV                          9
37 #define CLKID_SD_EMMC_A_CLK0_SEL                63
38 #define CLKID_SD_EMMC_A_CLK0_DIV                64
39 #define CLKID_SD_EMMC_B_CLK0_SEL                65
40 #define CLKID_SD_EMMC_B_CLK0_DIV                66
41 #define CLKID_SD_EMMC_C_CLK0_SEL                67
42 #define CLKID_SD_EMMC_C_CLK0_DIV                68
43 #define CLKID_MPLL0_DIV                         69
44 #define CLKID_MPLL1_DIV                         70
45 #define CLKID_MPLL2_DIV                         71
46 #define CLKID_MPLL3_DIV                         72
47 #define CLKID_MPLL_PREDIV                       73
48 #define CLKID_FCLK_DIV2_DIV                     75
49 #define CLKID_FCLK_DIV3_DIV                     76
50 #define CLKID_FCLK_DIV4_DIV                     77
51 #define CLKID_FCLK_DIV5_DIV                     78
52 #define CLKID_FCLK_DIV7_DIV                     79
53 #define CLKID_FCLK_DIV2P5_DIV                   100
54 #define CLKID_FIXED_PLL_DCO                     101
55 #define CLKID_SYS_PLL_DCO                       102
56 #define CLKID_GP0_PLL_DCO                       103
57 #define CLKID_HIFI_PLL_DCO                      104
58 #define CLKID_VPU_0_DIV                         111
59 #define CLKID_VPU_1_DIV                         114
60 #define CLKID_VAPB_0_DIV                        118
61 #define CLKID_VAPB_1_DIV                        121
62 #define CLKID_HDMI_PLL_DCO                      125
63 #define CLKID_HDMI_PLL_OD                       126
64 #define CLKID_HDMI_PLL_OD2                      127
65 #define CLKID_VID_PLL_SEL                       130
66 #define CLKID_VID_PLL_DIV                       131
67 #define CLKID_VCLK_SEL                          132
68 #define CLKID_VCLK2_SEL                         133
69 #define CLKID_VCLK_INPUT                        134
70 #define CLKID_VCLK2_INPUT                       135
71 #define CLKID_VCLK_DIV                          136
72 #define CLKID_VCLK2_DIV                         137
73 #define CLKID_VCLK_DIV2_EN                      140
74 #define CLKID_VCLK_DIV4_EN                      141
75 #define CLKID_VCLK_DIV6_EN                      142
76 #define CLKID_VCLK_DIV12_EN                     143
77 #define CLKID_VCLK2_DIV2_EN                     144
78 #define CLKID_VCLK2_DIV4_EN                     145
79 #define CLKID_VCLK2_DIV6_EN                     146
80 #define CLKID_VCLK2_DIV12_EN                    147
81 #define CLKID_CTS_ENCI_SEL                      158
82 #define CLKID_CTS_ENCP_SEL                      159
83 #define CLKID_CTS_VDAC_SEL                      160
84 #define CLKID_HDMI_TX_SEL                       161
85 #define CLKID_HDMI_SEL                          166
86 #define CLKID_HDMI_DIV                          167
87 #define CLKID_MALI_0_DIV                        170
88 #define CLKID_MALI_1_DIV                        173
89
90 #define CLKID_XTAL                              0x10000000
91
92 #define XTAL_RATE 24000000
93
94 struct meson_clk {
95         struct regmap *map;
96 };
97
98 static ulong meson_div_get_rate(struct clk *clk, unsigned long id);
99 static ulong meson_div_set_rate(struct clk *clk, unsigned long id, ulong rate,
100                                 ulong current_rate);
101 static ulong meson_mux_set_parent(struct clk *clk, unsigned long id,
102                                   unsigned long parent_id);
103 static ulong meson_mux_get_rate(struct clk *clk, unsigned long id);
104 static ulong meson_clk_set_rate_by_id(struct clk *clk, unsigned long id,
105                                       ulong rate, ulong current_rate);
106 static ulong meson_mux_get_parent(struct clk *clk, unsigned long id);
107 static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id);
108
109 #define NUM_CLKS 178
110
111 static struct meson_gate gates[NUM_CLKS] = {
112         /* Everything Else (EE) domain gates */
113         MESON_GATE(CLKID_SPICC0, HHI_GCLK_MPEG0, 8),
114         MESON_GATE(CLKID_I2C, HHI_GCLK_MPEG0, 9),
115         MESON_GATE(CLKID_UART0, HHI_GCLK_MPEG0, 13),
116         MESON_GATE(CLKID_SPICC1, HHI_GCLK_MPEG0, 14),
117         MESON_GATE(CLKID_SD_EMMC_A, HHI_GCLK_MPEG0, 4),
118         MESON_GATE(CLKID_SD_EMMC_B, HHI_GCLK_MPEG0, 25),
119         MESON_GATE(CLKID_SD_EMMC_C, HHI_GCLK_MPEG0, 26),
120         MESON_GATE(CLKID_ETH, HHI_GCLK_MPEG1, 3),
121         MESON_GATE(CLKID_UART1, HHI_GCLK_MPEG1, 16),
122         MESON_GATE(CLKID_USB, HHI_GCLK_MPEG1, 25),
123         MESON_GATE(CLKID_HTX_PCLK, HHI_GCLK_MPEG2, 4),
124         MESON_GATE(CLKID_USB1_DDR_BRIDGE, HHI_GCLK_MPEG2, 8),
125         MESON_GATE(CLKID_VPU_INTR, HHI_GCLK_MPEG2, 25),
126
127         /* Peripheral Gates */
128         MESON_GATE(CLKID_FCLK_DIV2, HHI_FIX_PLL_CNTL1, 24),
129         MESON_GATE(CLKID_FCLK_DIV3, HHI_FIX_PLL_CNTL1, 20),
130         MESON_GATE(CLKID_FCLK_DIV4, HHI_FIX_PLL_CNTL1, 21),
131         MESON_GATE(CLKID_FCLK_DIV5, HHI_FIX_PLL_CNTL1, 22),
132         MESON_GATE(CLKID_FCLK_DIV7, HHI_FIX_PLL_CNTL1, 23),
133         MESON_GATE(CLKID_SD_EMMC_A_CLK0, HHI_SD_EMMC_CLK_CNTL, 7),
134         MESON_GATE(CLKID_SD_EMMC_B_CLK0, HHI_SD_EMMC_CLK_CNTL, 23),
135         MESON_GATE(CLKID_SD_EMMC_C_CLK0, HHI_NAND_CLK_CNTL, 7),
136         MESON_GATE(CLKID_VPU_0, HHI_VPU_CLK_CNTL, 8),
137         MESON_GATE(CLKID_VPU_1, HHI_VPU_CLK_CNTL, 24),
138         MESON_GATE(CLKID_VAPB_0, HHI_VAPBCLK_CNTL, 8),
139         MESON_GATE(CLKID_VAPB_1, HHI_VAPBCLK_CNTL, 24),
140         MESON_GATE(CLKID_VAPB, HHI_VAPBCLK_CNTL, 30),
141         MESON_GATE(CLKID_HDMI, HHI_HDMI_CLK_CNTL, 8),
142 };
143
144 static int meson_set_gate_by_id(struct clk *clk, unsigned long id, bool on)
145 {
146         struct meson_clk *priv = dev_get_priv(clk->dev);
147         struct meson_gate *gate;
148
149         debug("%s: %sabling %ld\n", __func__, on ? "en" : "dis", id);
150
151         /* Propagate through muxes */
152         switch (id) {
153         case CLKID_VPU:
154                 return meson_set_gate_by_id(clk,
155                                 meson_mux_get_parent(clk, CLKID_VPU), on);
156         case CLKID_VAPB_SEL:
157                 return meson_set_gate_by_id(clk,
158                                 meson_mux_get_parent(clk, CLKID_VAPB_SEL), on);
159         }
160
161         if (id >= ARRAY_SIZE(gates))
162                 return -ENOENT;
163
164         gate = &gates[id];
165
166         if (gate->reg == 0)
167                 return 0;
168
169         debug("%s: really %sabling %ld\n", __func__, on ? "en" : "dis", id);
170
171         regmap_update_bits(priv->map, gate->reg,
172                            BIT(gate->bit), on ? BIT(gate->bit) : 0);
173
174         /* Propagate to next gate(s) */
175         switch (id) {
176         case CLKID_VAPB:
177                 return meson_set_gate_by_id(clk, CLKID_VAPB_SEL, on);
178         case CLKID_VAPB_0:
179                 return meson_set_gate_by_id(clk,
180                         meson_mux_get_parent(clk, CLKID_VAPB_0_SEL), on);
181         case CLKID_VAPB_1:
182                 return meson_set_gate_by_id(clk,
183                         meson_mux_get_parent(clk, CLKID_VAPB_0_SEL), on);
184         case CLKID_VPU_0:
185                 return meson_set_gate_by_id(clk,
186                         meson_mux_get_parent(clk, CLKID_VPU_0_SEL), on);
187         case CLKID_VPU_1:
188                 return meson_set_gate_by_id(clk,
189                         meson_mux_get_parent(clk, CLKID_VPU_1_SEL), on);
190         }
191
192         return 0;
193 }
194
195 static int meson_clk_enable(struct clk *clk)
196 {
197         return meson_set_gate_by_id(clk, clk->id, true);
198 }
199
200 static int meson_clk_disable(struct clk *clk)
201 {
202         return meson_set_gate_by_id(clk, clk->id, false);
203 }
204
205 static struct parm meson_vpu_0_div_parm = {
206         HHI_VPU_CLK_CNTL, 0, 7,
207 };
208
209 int meson_vpu_0_div_parent = CLKID_VPU_0_SEL;
210
211 static struct parm meson_vpu_1_div_parm = {
212         HHI_VPU_CLK_CNTL, 16, 7,
213 };
214
215 int meson_vpu_1_div_parent = CLKID_VPU_1_SEL;
216
217 static struct parm meson_vapb_0_div_parm = {
218         HHI_VAPBCLK_CNTL, 0, 7,
219 };
220
221 int meson_vapb_0_div_parent = CLKID_VAPB_0_SEL;
222
223 static struct parm meson_vapb_1_div_parm = {
224         HHI_VAPBCLK_CNTL, 16, 7,
225 };
226
227 int meson_vapb_1_div_parent = CLKID_VAPB_1_SEL;
228
229 static struct parm meson_hdmi_div_parm = {
230         HHI_HDMI_CLK_CNTL, 0, 7,
231 };
232
233 int meson_hdmi_div_parent = CLKID_HDMI_SEL;
234
235 static ulong meson_div_get_rate(struct clk *clk, unsigned long id)
236 {
237         struct meson_clk *priv = dev_get_priv(clk->dev);
238         unsigned int rate, parent_rate;
239         struct parm *parm;
240         int parent;
241         uint reg;
242
243         switch (id) {
244         case CLKID_VPU_0_DIV:
245                 parm = &meson_vpu_0_div_parm;
246                 parent = meson_vpu_0_div_parent;
247                 break;
248         case CLKID_VPU_1_DIV:
249                 parm = &meson_vpu_1_div_parm;
250                 parent = meson_vpu_1_div_parent;
251                 break;
252         case CLKID_VAPB_0_DIV:
253                 parm = &meson_vapb_0_div_parm;
254                 parent = meson_vapb_0_div_parent;
255                 break;
256         case CLKID_VAPB_1_DIV:
257                 parm = &meson_vapb_1_div_parm;
258                 parent = meson_vapb_1_div_parent;
259                 break;
260         case CLKID_HDMI_DIV:
261                 parm = &meson_hdmi_div_parm;
262                 parent = meson_hdmi_div_parent;
263                 break;
264         default:
265                 return -ENOENT;
266         }
267
268         regmap_read(priv->map, parm->reg_off, &reg);
269         reg = PARM_GET(parm->width, parm->shift, reg);
270
271         debug("%s: div of %ld is %d\n", __func__, id, reg + 1);
272
273         parent_rate = meson_clk_get_rate_by_id(clk, parent);
274         if (IS_ERR_VALUE(parent_rate))
275                 return parent_rate;
276
277         debug("%s: parent rate of %ld is %d\n", __func__, id, parent_rate);
278
279         rate = parent_rate / (reg + 1);
280
281         debug("%s: rate of %ld is %d\n", __func__, id, rate);
282
283         return rate;
284 }
285
286 static ulong meson_div_set_rate(struct clk *clk, unsigned long id, ulong rate,
287                                 ulong current_rate)
288 {
289         struct meson_clk *priv = dev_get_priv(clk->dev);
290         unsigned int new_div = -EINVAL;
291         unsigned long parent_rate;
292         struct parm *parm;
293         int parent;
294         int ret;
295
296         if (current_rate == rate)
297                 return 0;
298
299         debug("%s: setting rate of %ld from %ld to %ld\n",
300               __func__, id, current_rate, rate);
301
302         switch (id) {
303         case CLKID_VPU_0_DIV:
304                 parm = &meson_vpu_0_div_parm;
305                 parent = meson_vpu_0_div_parent;
306                 break;
307         case CLKID_VPU_1_DIV:
308                 parm = &meson_vpu_1_div_parm;
309                 parent = meson_vpu_1_div_parent;
310                 break;
311         case CLKID_VAPB_0_DIV:
312                 parm = &meson_vapb_0_div_parm;
313                 parent = meson_vapb_0_div_parent;
314                 break;
315         case CLKID_VAPB_1_DIV:
316                 parm = &meson_vapb_1_div_parm;
317                 parent = meson_vapb_1_div_parent;
318                 break;
319         case CLKID_HDMI_DIV:
320                 parm = &meson_hdmi_div_parm;
321                 parent = meson_hdmi_div_parent;
322                 break;
323         default:
324                 return -ENOENT;
325         }
326
327         parent_rate = meson_clk_get_rate_by_id(clk, parent);
328         if (IS_ERR_VALUE(parent_rate))
329                 return parent_rate;
330
331         debug("%s: parent rate of %ld is %ld\n", __func__, id, parent_rate);
332
333         /* If can't divide, set parent instead */
334         if (!parent_rate || rate > parent_rate)
335                 return meson_clk_set_rate_by_id(clk, parent, rate,
336                                                 current_rate);
337
338         new_div = DIV_ROUND_CLOSEST(parent_rate, rate);
339
340         debug("%s: new div of %ld is %d\n", __func__, id, new_div);
341
342         /* If overflow, try to set parent rate and retry */
343         if (!new_div || new_div > (1 << parm->width)) {
344                 ret = meson_clk_set_rate_by_id(clk, parent, rate, current_rate);
345                 if (IS_ERR_VALUE(ret))
346                         return ret;
347
348                 parent_rate = meson_clk_get_rate_by_id(clk, parent);
349                 if (IS_ERR_VALUE(parent_rate))
350                         return parent_rate;
351
352                 new_div = DIV_ROUND_CLOSEST(parent_rate, rate);
353
354                 debug("%s: new new div of %ld is %d\n", __func__, id, new_div);
355
356                 if (!new_div || new_div > (1 << parm->width))
357                         return -EINVAL;
358         }
359
360         debug("%s: setting div of %ld to %d\n", __func__, id, new_div);
361
362         regmap_update_bits(priv->map, parm->reg_off,
363                            SETPMASK(parm->width, parm->shift),
364                            (new_div - 1) << parm->shift);
365
366         debug("%s: new rate of %ld is %ld\n",
367               __func__, id, meson_div_get_rate(clk, id));
368
369         return 0;
370 }
371
372 static struct parm meson_vpu_mux_parm = {
373         HHI_VPU_CLK_CNTL, 31, 1,
374 };
375
376 int meson_vpu_mux_parents[] = {
377         CLKID_VPU_0,
378         CLKID_VPU_1,
379 };
380
381 static struct parm meson_vpu_0_mux_parm = {
382         HHI_VPU_CLK_CNTL, 9, 3,
383 };
384
385 static struct parm meson_vpu_1_mux_parm = {
386         HHI_VPU_CLK_CNTL, 25, 3,
387 };
388
389 static int meson_vpu_0_1_mux_parents[] = {
390         CLKID_FCLK_DIV3,
391         CLKID_FCLK_DIV4,
392         CLKID_FCLK_DIV5,
393         CLKID_FCLK_DIV7,
394         -ENOENT,
395         -ENOENT,
396         -ENOENT,
397         -ENOENT,
398 };
399
400 static struct parm meson_vapb_sel_mux_parm = {
401         HHI_VAPBCLK_CNTL, 31, 1,
402 };
403
404 int meson_vapb_sel_mux_parents[] = {
405         CLKID_VAPB_0,
406         CLKID_VAPB_1,
407 };
408
409 static struct parm meson_vapb_0_mux_parm = {
410         HHI_VAPBCLK_CNTL, 9, 2,
411 };
412
413 static struct parm meson_vapb_1_mux_parm = {
414         HHI_VAPBCLK_CNTL, 25, 2,
415 };
416
417 static int meson_vapb_0_1_mux_parents[] = {
418         CLKID_FCLK_DIV4,
419         CLKID_FCLK_DIV3,
420         CLKID_FCLK_DIV5,
421         CLKID_FCLK_DIV7,
422 };
423
424 static struct parm meson_hdmi_mux_parm = {
425         HHI_HDMI_CLK_CNTL, 9, 2,
426 };
427
428 static int meson_hdmi_mux_parents[] = {
429         CLKID_XTAL,
430         CLKID_FCLK_DIV4,
431         CLKID_FCLK_DIV3,
432         CLKID_FCLK_DIV5,
433 };
434
435 static ulong meson_mux_get_parent(struct clk *clk, unsigned long id)
436 {
437         struct meson_clk *priv = dev_get_priv(clk->dev);
438         struct parm *parm;
439         int *parents;
440         uint reg;
441
442         switch (id) {
443         case CLKID_VPU:
444                 parm = &meson_vpu_mux_parm;
445                 parents = meson_vpu_mux_parents;
446                 break;
447         case CLKID_VPU_0_SEL:
448                 parm = &meson_vpu_0_mux_parm;
449                 parents = meson_vpu_0_1_mux_parents;
450                 break;
451         case CLKID_VPU_1_SEL:
452                 parm = &meson_vpu_1_mux_parm;
453                 parents = meson_vpu_0_1_mux_parents;
454                 break;
455         case CLKID_VAPB_SEL:
456                 parm = &meson_vapb_sel_mux_parm;
457                 parents = meson_vapb_sel_mux_parents;
458                 break;
459         case CLKID_VAPB_0_SEL:
460                 parm = &meson_vapb_0_mux_parm;
461                 parents = meson_vapb_0_1_mux_parents;
462                 break;
463         case CLKID_VAPB_1_SEL:
464                 parm = &meson_vapb_1_mux_parm;
465                 parents = meson_vapb_0_1_mux_parents;
466                 break;
467         case CLKID_HDMI_SEL:
468                 parm = &meson_hdmi_mux_parm;
469                 parents = meson_hdmi_mux_parents;
470                 break;
471         default:
472                 return -ENOENT;
473         }
474
475         regmap_read(priv->map, parm->reg_off, &reg);
476         reg = PARM_GET(parm->width, parm->shift, reg);
477
478         debug("%s: parent of %ld is %d (%d)\n",
479               __func__, id, parents[reg], reg);
480
481         return parents[reg];
482 }
483
484 static ulong meson_mux_set_parent(struct clk *clk, unsigned long id,
485                                   unsigned long parent_id)
486 {
487         unsigned long cur_parent = meson_mux_get_parent(clk, id);
488         struct meson_clk *priv = dev_get_priv(clk->dev);
489         unsigned int new_index = -EINVAL;
490         struct parm *parm;
491         int *parents;
492         int i;
493
494         if (IS_ERR_VALUE(cur_parent))
495                 return cur_parent;
496
497         debug("%s: setting parent of %ld from %ld to %ld\n",
498               __func__, id, cur_parent, parent_id);
499
500         if (cur_parent == parent_id)
501                 return 0;
502
503         switch (id) {
504         case CLKID_VPU:
505                 parm = &meson_vpu_mux_parm;
506                 parents = meson_vpu_mux_parents;
507                 break;
508         case CLKID_VPU_0_SEL:
509                 parm = &meson_vpu_0_mux_parm;
510                 parents = meson_vpu_0_1_mux_parents;
511                 break;
512         case CLKID_VPU_1_SEL:
513                 parm = &meson_vpu_1_mux_parm;
514                 parents = meson_vpu_0_1_mux_parents;
515                 break;
516         case CLKID_VAPB_SEL:
517                 parm = &meson_vapb_sel_mux_parm;
518                 parents = meson_vapb_sel_mux_parents;
519                 break;
520         case CLKID_VAPB_0_SEL:
521                 parm = &meson_vapb_0_mux_parm;
522                 parents = meson_vapb_0_1_mux_parents;
523                 break;
524         case CLKID_VAPB_1_SEL:
525                 parm = &meson_vapb_1_mux_parm;
526                 parents = meson_vapb_0_1_mux_parents;
527                 break;
528         case CLKID_HDMI_SEL:
529                 parm = &meson_hdmi_mux_parm;
530                 parents = meson_hdmi_mux_parents;
531                 break;
532         default:
533                 /* Not a mux */
534                 return -ENOENT;
535         }
536
537         for (i = 0 ; i < (1 << parm->width) ; ++i) {
538                 if (parents[i] == parent_id)
539                         new_index = i;
540         }
541
542         if (IS_ERR_VALUE(new_index))
543                 return new_index;
544
545         debug("%s: new index of %ld is %d\n", __func__, id, new_index);
546
547         regmap_update_bits(priv->map, parm->reg_off,
548                            SETPMASK(parm->width, parm->shift),
549                            new_index << parm->shift);
550
551         debug("%s: new parent of %ld is %ld\n",
552               __func__, id, meson_mux_get_parent(clk, id));
553
554         return 0;
555 }
556
557 static ulong meson_mux_get_rate(struct clk *clk, unsigned long id)
558 {
559         int parent = meson_mux_get_parent(clk, id);
560
561         if (IS_ERR_VALUE(parent))
562                 return parent;
563
564         return meson_clk_get_rate_by_id(clk, parent);
565 }
566
567 static unsigned long meson_clk81_get_rate(struct clk *clk)
568 {
569         struct meson_clk *priv = dev_get_priv(clk->dev);
570         unsigned long parent_rate;
571         uint reg;
572         int parents[] = {
573                 CLKID_XTAL,
574                 -1,
575                 CLKID_FCLK_DIV7,
576                 CLKID_MPLL1,
577                 CLKID_MPLL2,
578                 CLKID_FCLK_DIV4,
579                 CLKID_FCLK_DIV3,
580                 CLKID_FCLK_DIV5
581         };
582
583         /* mux */
584         regmap_read(priv->map, HHI_MPEG_CLK_CNTL, &reg);
585         reg = (reg >> 12) & 7;
586
587         switch (reg) {
588         case 1:
589                 return -ENOENT;
590         default:
591                 parent_rate = meson_clk_get_rate_by_id(clk, parents[reg]);
592         }
593
594         /* divider */
595         regmap_read(priv->map, HHI_MPEG_CLK_CNTL, &reg);
596         reg = reg & ((1 << 7) - 1);
597
598         return parent_rate / reg;
599 }
600
601 static long mpll_rate_from_params(unsigned long parent_rate,
602                                   unsigned long sdm,
603                                   unsigned long n2)
604 {
605         unsigned long divisor = (SDM_DEN * n2) + sdm;
606
607         if (n2 < N2_MIN)
608                 return -EINVAL;
609
610         return DIV_ROUND_UP_ULL((u64)parent_rate * SDM_DEN, divisor);
611 }
612
613 static struct parm meson_mpll0_parm[2] = {
614         {HHI_MPLL_CNTL1, 0, 14}, /* psdm */
615         {HHI_MPLL_CNTL1, 20, 9}, /* pn2 */
616 };
617
618 static struct parm meson_mpll1_parm[2] = {
619         {HHI_MPLL_CNTL3, 0, 14}, /* psdm */
620         {HHI_MPLL_CNTL3, 20, 9}, /* pn2 */
621 };
622
623 static struct parm meson_mpll2_parm[2] = {
624         {HHI_MPLL_CNTL5, 0, 14}, /* psdm */
625         {HHI_MPLL_CNTL5, 20, 9}, /* pn2 */
626 };
627
628 /*
629  * MultiPhase Locked Loops are outputs from a PLL with additional frequency
630  * scaling capabilities. MPLL rates are calculated as:
631  *
632  * f(N2_integer, SDM_IN ) = 2.0G/(N2_integer + SDM_IN/16384)
633  */
634 static ulong meson_mpll_get_rate(struct clk *clk, unsigned long id)
635 {
636         struct meson_clk *priv = dev_get_priv(clk->dev);
637         struct parm *psdm, *pn2;
638         unsigned long sdm, n2;
639         unsigned long parent_rate;
640         uint reg;
641
642         switch (id) {
643         case CLKID_MPLL0:
644                 psdm = &meson_mpll0_parm[0];
645                 pn2 = &meson_mpll0_parm[1];
646                 break;
647         case CLKID_MPLL1:
648                 psdm = &meson_mpll1_parm[0];
649                 pn2 = &meson_mpll1_parm[1];
650                 break;
651         case CLKID_MPLL2:
652                 psdm = &meson_mpll2_parm[0];
653                 pn2 = &meson_mpll2_parm[1];
654                 break;
655         default:
656                 return -ENOENT;
657         }
658
659         parent_rate = meson_clk_get_rate_by_id(clk, CLKID_FIXED_PLL);
660         if (IS_ERR_VALUE(parent_rate))
661                 return parent_rate;
662
663         regmap_read(priv->map, psdm->reg_off, &reg);
664         sdm = PARM_GET(psdm->width, psdm->shift, reg);
665
666         regmap_read(priv->map, pn2->reg_off, &reg);
667         n2 = PARM_GET(pn2->width, pn2->shift, reg);
668
669         return mpll_rate_from_params(parent_rate, sdm, n2);
670 }
671
672 static struct parm meson_fixed_pll_parm[4] = {
673         {HHI_FIX_PLL_CNTL0, 0, 9}, /* pm */
674         {HHI_FIX_PLL_CNTL0, 10, 5}, /* pn */
675         {HHI_FIX_PLL_CNTL0, 16, 2}, /* pod */
676         {HHI_FIX_PLL_CNTL1, 0, 17}, /* pfrac */
677 };
678
679 static struct parm meson_sys_pll_parm[3] = {
680         {HHI_SYS_PLL_CNTL0, 0, 9}, /* pm */
681         {HHI_SYS_PLL_CNTL0, 10, 5}, /* pn */
682         {HHI_SYS_PLL_CNTL0, 16, 3}, /* pod */
683 };
684
685 static ulong meson_pll_get_rate(struct clk *clk, unsigned long id)
686 {
687         struct meson_clk *priv = dev_get_priv(clk->dev);
688         struct parm *pm, *pn, *pod, *pfrac = NULL;
689         unsigned long parent_rate_mhz = XTAL_RATE / 1000000;
690         u16 n, m, od, frac;
691         ulong rate;
692         uint reg;
693
694         /*
695          * FIXME: Between the unit conversion and the missing frac, we know
696          * rate will be slightly off ...
697         */
698
699         switch (id) {
700         case CLKID_FIXED_PLL:
701                 pm = &meson_fixed_pll_parm[0];
702                 pn = &meson_fixed_pll_parm[1];
703                 pod = &meson_fixed_pll_parm[2];
704                 pfrac = &meson_fixed_pll_parm[3];
705                 break;
706         case CLKID_SYS_PLL:
707                 pm = &meson_sys_pll_parm[0];
708                 pn = &meson_sys_pll_parm[1];
709                 pod = &meson_sys_pll_parm[2];
710                 break;
711         default:
712                 return -ENOENT;
713         }
714
715         regmap_read(priv->map, pn->reg_off, &reg);
716         n = PARM_GET(pn->width, pn->shift, reg);
717
718         regmap_read(priv->map, pm->reg_off, &reg);
719         m = PARM_GET(pm->width, pm->shift, reg);
720
721         regmap_read(priv->map, pod->reg_off, &reg);
722         od = PARM_GET(pod->width, pod->shift, reg);
723
724         rate = parent_rate_mhz * m;
725
726         if (pfrac) {
727                 ulong frac_rate;
728
729                 regmap_read(priv->map, pfrac->reg_off, &reg);
730                 frac = PARM_GET(pfrac->width - 1, pfrac->shift, reg);
731
732                 frac_rate = DIV_ROUND_UP_ULL((u64)parent_rate_mhz * frac,
733                                              1 << (pfrac->width - 2));
734
735                 if (frac & BIT(pfrac->width - 1))
736                         rate -= frac_rate;
737                 else
738                         rate += frac_rate;
739         }
740
741         return (DIV_ROUND_UP_ULL(rate, n) >> od) * 1000000;
742 }
743
744 static struct parm meson_pcie_pll_parm[3] = {
745         {HHI_PCIE_PLL_CNTL0, 0, 8}, /* pm */
746         {HHI_PCIE_PLL_CNTL0, 10, 5}, /* pn */
747         {HHI_PCIE_PLL_CNTL0, 16, 5}, /* pod */
748 };
749
750 static ulong meson_pcie_pll_get_rate(struct clk *clk)
751 {
752         struct meson_clk *priv = dev_get_priv(clk->dev);
753         struct parm *pm, *pn, *pod;
754         unsigned long parent_rate_mhz = XTAL_RATE / 1000000;
755         u16 n, m, od;
756         uint reg;
757
758         pm = &meson_pcie_pll_parm[0];
759         pn = &meson_pcie_pll_parm[1];
760         pod = &meson_pcie_pll_parm[2];
761
762         regmap_read(priv->map, pn->reg_off, &reg);
763         n = PARM_GET(pn->width, pn->shift, reg);
764
765         regmap_read(priv->map, pm->reg_off, &reg);
766         m = PARM_GET(pm->width, pm->shift, reg);
767
768         regmap_read(priv->map, pod->reg_off, &reg);
769         od = PARM_GET(pod->width, pod->shift, reg);
770
771         return ((parent_rate_mhz * m / n) / 2 / od / 2) * 1000000;
772 }
773
774 static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id)
775 {
776         ulong rate;
777
778         switch (id) {
779         case CLKID_XTAL:
780                 rate = XTAL_RATE;
781                 break;
782         case CLKID_FIXED_PLL:
783         case CLKID_SYS_PLL:
784                 rate = meson_pll_get_rate(clk, id);
785                 break;
786         case CLKID_FCLK_DIV2:
787                 rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 2;
788                 break;
789         case CLKID_FCLK_DIV3:
790                 rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 3;
791                 break;
792         case CLKID_FCLK_DIV4:
793                 rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 4;
794                 break;
795         case CLKID_FCLK_DIV5:
796                 rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 5;
797                 break;
798         case CLKID_FCLK_DIV7:
799                 rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 7;
800                 break;
801         case CLKID_MPLL0:
802         case CLKID_MPLL1:
803         case CLKID_MPLL2:
804                 rate = meson_mpll_get_rate(clk, id);
805                 break;
806         case CLKID_CLK81:
807                 rate = meson_clk81_get_rate(clk);
808                 break;
809         case CLKID_PCIE_PLL:
810                 rate = meson_pcie_pll_get_rate(clk);
811                 break;
812         case CLKID_VPU_0:
813                 rate = meson_div_get_rate(clk, CLKID_VPU_0_DIV);
814                 break;
815         case CLKID_VPU_1:
816                 rate = meson_div_get_rate(clk, CLKID_VPU_1_DIV);
817                 break;
818         case CLKID_VAPB:
819                 rate = meson_mux_get_rate(clk, CLKID_VAPB_SEL);
820                 break;
821         case CLKID_VAPB_0:
822                 rate = meson_div_get_rate(clk, CLKID_VAPB_0_DIV);
823                 break;
824         case CLKID_VAPB_1:
825                 rate = meson_div_get_rate(clk, CLKID_VAPB_1_DIV);
826                 break;
827         case CLKID_HDMI:
828                 rate = meson_div_get_rate(clk, CLKID_HDMI_DIV);
829                 break;
830         case CLKID_VPU_0_DIV:
831         case CLKID_VPU_1_DIV:
832         case CLKID_VAPB_0_DIV:
833         case CLKID_VAPB_1_DIV:
834         case CLKID_HDMI_DIV:
835                 rate = meson_div_get_rate(clk, id);
836                 break;
837         case CLKID_VPU:
838         case CLKID_VPU_0_SEL:
839         case CLKID_VPU_1_SEL:
840         case CLKID_VAPB_SEL:
841         case CLKID_VAPB_0_SEL:
842         case CLKID_VAPB_1_SEL:
843         case CLKID_HDMI_SEL:
844                 rate = meson_mux_get_rate(clk, id);
845                 break;
846         default:
847                 if (gates[id].reg != 0) {
848                         /* a clock gate */
849                         rate = meson_clk81_get_rate(clk);
850                         break;
851                 }
852                 return -ENOENT;
853         }
854
855         debug("clock %lu has rate %lu\n", id, rate);
856         return rate;
857 }
858
859 static ulong meson_clk_get_rate(struct clk *clk)
860 {
861         return meson_clk_get_rate_by_id(clk, clk->id);
862 }
863
864 static ulong meson_pcie_pll_set_rate(struct clk *clk, ulong rate)
865 {
866         struct meson_clk *priv = dev_get_priv(clk->dev);
867
868         regmap_write(priv->map, HHI_PCIE_PLL_CNTL0, 0x20090496);
869         regmap_write(priv->map, HHI_PCIE_PLL_CNTL0, 0x30090496);
870         regmap_write(priv->map, HHI_PCIE_PLL_CNTL1, 0x00000000);
871         regmap_write(priv->map, HHI_PCIE_PLL_CNTL2, 0x00001100);
872         regmap_write(priv->map, HHI_PCIE_PLL_CNTL3, 0x10058e00);
873         regmap_write(priv->map, HHI_PCIE_PLL_CNTL4, 0x000100c0);
874         regmap_write(priv->map, HHI_PCIE_PLL_CNTL5, 0x68000048);
875         regmap_write(priv->map, HHI_PCIE_PLL_CNTL5, 0x68000068);
876         udelay(20);
877         regmap_write(priv->map, HHI_PCIE_PLL_CNTL4, 0x008100c0);
878         udelay(10);
879         regmap_write(priv->map, HHI_PCIE_PLL_CNTL0, 0x34090496);
880         regmap_write(priv->map, HHI_PCIE_PLL_CNTL0, 0x14090496);
881         udelay(10);
882         regmap_write(priv->map, HHI_PCIE_PLL_CNTL2, 0x00001000);
883         regmap_update_bits(priv->map, HHI_PCIE_PLL_CNTL0,
884                                 0x1f << 16, 9 << 16);
885
886         return 100000000;
887 }
888
889 static int meson_clk_set_parent(struct clk *clk, struct clk *parent)
890 {
891         return meson_mux_set_parent(clk, clk->id, parent->id);
892 }
893
894 static ulong meson_clk_set_rate_by_id(struct clk *clk, unsigned long id,
895                                       ulong rate, ulong current_rate)
896 {
897         if (current_rate == rate)
898                 return 0;
899
900         switch (id) {
901         /* Fixed clocks */
902         case CLKID_FIXED_PLL:
903         case CLKID_SYS_PLL:
904         case CLKID_FCLK_DIV2:
905         case CLKID_FCLK_DIV3:
906         case CLKID_FCLK_DIV4:
907         case CLKID_FCLK_DIV5:
908         case CLKID_FCLK_DIV7:
909         case CLKID_MPLL0:
910         case CLKID_MPLL1:
911         case CLKID_MPLL2:
912         case CLKID_CLK81:
913                 if (current_rate != rate)
914                         return -EINVAL;
915         case CLKID_PCIE_PLL:
916                 return meson_pcie_pll_set_rate(clk, rate);
917
918                 return 0;
919         case CLKID_VPU:
920                 return meson_clk_set_rate_by_id(clk,
921                                 meson_mux_get_parent(clk, CLKID_VPU), rate,
922                                                      current_rate);
923         case CLKID_VAPB:
924         case CLKID_VAPB_SEL:
925                 return meson_clk_set_rate_by_id(clk,
926                                 meson_mux_get_parent(clk, CLKID_VAPB_SEL),
927                                 rate, current_rate);
928         case CLKID_VPU_0:
929                 return meson_div_set_rate(clk, CLKID_VPU_0_DIV, rate,
930                                           current_rate);
931         case CLKID_VPU_1:
932                 return meson_div_set_rate(clk, CLKID_VPU_1_DIV, rate,
933                                           current_rate);
934         case CLKID_VAPB_0:
935                 return meson_div_set_rate(clk, CLKID_VAPB_0_DIV, rate,
936                                           current_rate);
937         case CLKID_VAPB_1:
938                 return meson_div_set_rate(clk, CLKID_VAPB_1_DIV, rate,
939                                           current_rate);
940         case CLKID_VPU_0_DIV:
941         case CLKID_VPU_1_DIV:
942         case CLKID_VAPB_0_DIV:
943         case CLKID_VAPB_1_DIV:
944         case CLKID_HDMI_DIV:
945                 return meson_div_set_rate(clk, id, rate, current_rate);
946         case CLKID_HDMI:
947                 return meson_clk_set_rate_by_id(clk, CLKID_HDMI_DIV,
948                                                 rate, current_rate);
949         default:
950                 return -ENOENT;
951         }
952
953         return -EINVAL;
954 }
955
956 static ulong meson_clk_set_rate(struct clk *clk, ulong rate)
957 {
958         ulong current_rate = meson_clk_get_rate_by_id(clk, clk->id);
959         int ret;
960
961         if (IS_ERR_VALUE(current_rate))
962                 return current_rate;
963
964         debug("%s: setting rate of %ld from %ld to %ld\n",
965               __func__, clk->id, current_rate, rate);
966
967         ret = meson_clk_set_rate_by_id(clk, clk->id, rate, current_rate);
968         if (IS_ERR_VALUE(ret))
969                 return ret;
970
971         debug("clock %lu has new rate %lu\n", clk->id,
972               meson_clk_get_rate_by_id(clk, clk->id));
973
974         return 0;
975 }
976
977 static int meson_clk_probe(struct udevice *dev)
978 {
979         struct meson_clk *priv = dev_get_priv(dev);
980
981         priv->map = syscon_node_to_regmap(dev_get_parent(dev)->node);
982         if (IS_ERR(priv->map))
983                 return PTR_ERR(priv->map);
984
985         /*
986          * Depending on the boot src, the state of the MMC clock might
987          * be different. Reset it to make sure we won't get stuck
988          */
989         regmap_write(priv->map, HHI_NAND_CLK_CNTL, 0);
990         regmap_write(priv->map, HHI_SD_EMMC_CLK_CNTL, 0);
991
992         debug("meson-clk-g12a: probed\n");
993
994         return 0;
995 }
996
997 static struct clk_ops meson_clk_ops = {
998         .disable        = meson_clk_disable,
999         .enable         = meson_clk_enable,
1000         .get_rate       = meson_clk_get_rate,
1001         .set_parent     = meson_clk_set_parent,
1002         .set_rate       = meson_clk_set_rate,
1003 };
1004
1005 static const struct udevice_id meson_clk_ids[] = {
1006         { .compatible = "amlogic,g12a-clkc" },
1007         { .compatible = "amlogic,g12b-clkc" },
1008         { .compatible = "amlogic,sm1-clkc" },
1009         { }
1010 };
1011
1012 U_BOOT_DRIVER(meson_clk_g12a) = {
1013         .name           = "meson_clk_g12a",
1014         .id             = UCLASS_CLK,
1015         .of_match       = meson_clk_ids,
1016         .priv_auto_alloc_size = sizeof(struct meson_clk),
1017         .ops            = &meson_clk_ops,
1018         .probe          = meson_clk_probe,
1019 };