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