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