Merge tag 'efi-2019-04-rc2' of https://github.com/xypron2/u-boot
[platform/kernel/u-boot.git] / drivers / video / meson / meson_vclk.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Amlogic Meson Video Processing Unit driver
4  *
5  * Copyright (c) 2018 BayLibre, SAS.
6  * Author: Neil Armstrong <narmstrong@baylibre.com>
7  */
8
9 #include <edid.h>
10 #include "meson_vpu.h"
11 #include <linux/iopoll.h>
12 #include <linux/math64.h>
13
14 #define writel_bits(mask, val, addr) \
15         writel((readl(addr) & ~(mask)) | (val), addr)
16
17 enum {
18         MESON_VCLK_TARGET_CVBS = 0,
19         MESON_VCLK_TARGET_HDMI = 1,
20         MESON_VCLK_TARGET_DMT = 2,
21 };
22
23 /* HHI Registers */
24 #define HHI_VID_PLL_CLK_DIV     0x1a0 /* 0x68 offset in data sheet */
25 #define VID_PLL_EN              BIT(19)
26 #define VID_PLL_BYPASS          BIT(18)
27 #define VID_PLL_PRESET          BIT(15)
28 #define HHI_VIID_CLK_DIV        0x128 /* 0x4a offset in data sheet */
29 #define VCLK2_DIV_MASK          0xff
30 #define VCLK2_DIV_EN            BIT(16)
31 #define VCLK2_DIV_RESET         BIT(17)
32 #define CTS_VDAC_SEL_MASK       (0xf << 28)
33 #define CTS_VDAC_SEL_SHIFT      28
34 #define HHI_VIID_CLK_CNTL       0x12c /* 0x4b offset in data sheet */
35 #define VCLK2_EN                BIT(19)
36 #define VCLK2_SEL_MASK          (0x7 << 16)
37 #define VCLK2_SEL_SHIFT         16
38 #define VCLK2_SOFT_RESET        BIT(15)
39 #define VCLK2_DIV1_EN           BIT(0)
40 #define HHI_VID_CLK_DIV         0x164 /* 0x59 offset in data sheet */
41 #define VCLK_DIV_MASK           0xff
42 #define VCLK_DIV_EN             BIT(16)
43 #define VCLK_DIV_RESET          BIT(17)
44 #define CTS_ENCP_SEL_MASK       (0xf << 24)
45 #define CTS_ENCP_SEL_SHIFT      24
46 #define CTS_ENCI_SEL_MASK       (0xf << 28)
47 #define CTS_ENCI_SEL_SHIFT      28
48 #define HHI_VID_CLK_CNTL        0x17c /* 0x5f offset in data sheet */
49 #define VCLK_EN                 BIT(19)
50 #define VCLK_SEL_MASK           (0x7 << 16)
51 #define VCLK_SEL_SHIFT          16
52 #define VCLK_SOFT_RESET         BIT(15)
53 #define VCLK_DIV1_EN            BIT(0)
54 #define VCLK_DIV2_EN            BIT(1)
55 #define VCLK_DIV4_EN            BIT(2)
56 #define VCLK_DIV6_EN            BIT(3)
57 #define VCLK_DIV12_EN           BIT(4)
58 #define HHI_VID_CLK_CNTL2       0x194 /* 0x65 offset in data sheet */
59 #define CTS_ENCI_EN             BIT(0)
60 #define CTS_ENCP_EN             BIT(2)
61 #define CTS_VDAC_EN             BIT(4)
62 #define HDMI_TX_PIXEL_EN        BIT(5)
63 #define HHI_HDMI_CLK_CNTL       0x1cc /* 0x73 offset in data sheet */
64 #define HDMI_TX_PIXEL_SEL_MASK  (0xf << 16)
65 #define HDMI_TX_PIXEL_SEL_SHIFT 16
66 #define CTS_HDMI_SYS_SEL_MASK   (0x7 << 9)
67 #define CTS_HDMI_SYS_DIV_MASK   (0x7f)
68 #define CTS_HDMI_SYS_EN         BIT(8)
69
70 #define HHI_HDMI_PLL_CNTL       0x320 /* 0xc8 offset in data sheet */
71 #define HHI_HDMI_PLL_CNTL2      0x324 /* 0xc9 offset in data sheet */
72 #define HHI_HDMI_PLL_CNTL3      0x328 /* 0xca offset in data sheet */
73 #define HHI_HDMI_PLL_CNTL4      0x32C /* 0xcb offset in data sheet */
74 #define HHI_HDMI_PLL_CNTL5      0x330 /* 0xcc offset in data sheet */
75 #define HHI_HDMI_PLL_CNTL6      0x334 /* 0xcd offset in data sheet */
76
77 #define HDMI_PLL_RESET          BIT(28)
78 #define HDMI_PLL_LOCK           BIT(31)
79
80 /* VID PLL Dividers */
81 enum {
82         VID_PLL_DIV_1 = 0,
83         VID_PLL_DIV_2,
84         VID_PLL_DIV_2p5,
85         VID_PLL_DIV_3,
86         VID_PLL_DIV_3p5,
87         VID_PLL_DIV_3p75,
88         VID_PLL_DIV_4,
89         VID_PLL_DIV_5,
90         VID_PLL_DIV_6,
91         VID_PLL_DIV_6p25,
92         VID_PLL_DIV_7,
93         VID_PLL_DIV_7p5,
94         VID_PLL_DIV_12,
95         VID_PLL_DIV_14,
96         VID_PLL_DIV_15,
97 };
98
99 void meson_vid_pll_set(struct meson_vpu_priv *priv, unsigned int div)
100 {
101         unsigned int shift_val = 0;
102         unsigned int shift_sel = 0;
103
104         /* Disable vid_pll output clock */
105         hhi_update_bits(HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0);
106         hhi_update_bits(HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0);
107
108         switch (div) {
109         case VID_PLL_DIV_2:
110                 shift_val = 0x0aaa;
111                 shift_sel = 0;
112                 break;
113         case VID_PLL_DIV_2p5:
114                 shift_val = 0x5294;
115                 shift_sel = 2;
116                 break;
117         case VID_PLL_DIV_3:
118                 shift_val = 0x0db6;
119                 shift_sel = 0;
120                 break;
121         case VID_PLL_DIV_3p5:
122                 shift_val = 0x36cc;
123                 shift_sel = 1;
124                 break;
125         case VID_PLL_DIV_3p75:
126                 shift_val = 0x6666;
127                 shift_sel = 2;
128                 break;
129         case VID_PLL_DIV_4:
130                 shift_val = 0x0ccc;
131                 shift_sel = 0;
132                 break;
133         case VID_PLL_DIV_5:
134                 shift_val = 0x739c;
135                 shift_sel = 2;
136                 break;
137         case VID_PLL_DIV_6:
138                 shift_val = 0x0e38;
139                 shift_sel = 0;
140                 break;
141         case VID_PLL_DIV_6p25:
142                 shift_val = 0x0000;
143                 shift_sel = 3;
144                 break;
145         case VID_PLL_DIV_7:
146                 shift_val = 0x3c78;
147                 shift_sel = 1;
148                 break;
149         case VID_PLL_DIV_7p5:
150                 shift_val = 0x78f0;
151                 shift_sel = 2;
152                 break;
153         case VID_PLL_DIV_12:
154                 shift_val = 0x0fc0;
155                 shift_sel = 0;
156                 break;
157         case VID_PLL_DIV_14:
158                 shift_val = 0x3f80;
159                 shift_sel = 1;
160                 break;
161         case VID_PLL_DIV_15:
162                 shift_val = 0x7f80;
163                 shift_sel = 2;
164                 break;
165         }
166
167         if (div == VID_PLL_DIV_1) {
168                 /* Enable vid_pll bypass to HDMI pll */
169                 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
170                                 VID_PLL_BYPASS, VID_PLL_BYPASS);
171         } else {
172                 /* Disable Bypass */
173                 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
174                                 VID_PLL_BYPASS, 0);
175                 /* Clear sel */
176                 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
177                                 3 << 16, 0);
178                 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
179                                 VID_PLL_PRESET, 0);
180                 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
181                                 0x7fff, 0);
182
183                 /* Setup sel and val */
184                 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
185                                 3 << 16, shift_sel << 16);
186                 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
187                                 VID_PLL_PRESET, VID_PLL_PRESET);
188                 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
189                                 0x7fff, shift_val);
190
191                 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
192                                 VID_PLL_PRESET, 0);
193         }
194
195         /* Enable the vid_pll output clock */
196         hhi_update_bits(HHI_VID_PLL_CLK_DIV,
197                         VID_PLL_EN, VID_PLL_EN);
198 }
199
200 /*
201  * Setup VCLK2 for 27MHz, and enable clocks for ENCI and VDAC
202  *
203  * TOFIX: Refactor into table to also handle HDMI frequency and paths
204  */
205 static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv)
206 {
207         unsigned int val;
208
209         debug("%s:%d\n", __func__, __LINE__);
210
211         /* Setup PLL to output 1.485GHz */
212         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
213                 hhi_write(HHI_HDMI_PLL_CNTL, 0x5800023d);
214                 hhi_write(HHI_HDMI_PLL_CNTL2, 0x00404e00);
215                 hhi_write(HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
216                 hhi_write(HHI_HDMI_PLL_CNTL4, 0x801da72c);
217                 hhi_write(HHI_HDMI_PLL_CNTL5, 0x71486980);
218                 hhi_write(HHI_HDMI_PLL_CNTL6, 0x00000e55);
219                 hhi_write(HHI_HDMI_PLL_CNTL, 0x4800023d);
220         } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
221                    meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
222                 hhi_write(HHI_HDMI_PLL_CNTL, 0x4000027b);
223                 hhi_write(HHI_HDMI_PLL_CNTL2, 0x800cb300);
224                 hhi_write(HHI_HDMI_PLL_CNTL3, 0xa6212844);
225                 hhi_write(HHI_HDMI_PLL_CNTL4, 0x0c4d000c);
226                 hhi_write(HHI_HDMI_PLL_CNTL5, 0x001fa729);
227                 hhi_write(HHI_HDMI_PLL_CNTL6, 0x01a31500);
228
229                 /* Reset PLL */
230                 hhi_update_bits(HHI_HDMI_PLL_CNTL,
231                                 HDMI_PLL_RESET, HDMI_PLL_RESET);
232                 hhi_update_bits(HHI_HDMI_PLL_CNTL,
233                                 HDMI_PLL_RESET, 0);
234         }
235
236         debug("%s:%d\n", __func__, __LINE__);
237
238         /* Poll for lock bit */
239         readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
240                            (val & HDMI_PLL_LOCK), 10);
241
242         /* Disable VCLK2 */
243         hhi_update_bits(HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
244
245         /* Setup vid_pll to /1 */
246         meson_vid_pll_set(priv, VID_PLL_DIV_1);
247
248         /* Setup the VCLK2 divider value to achieve 27MHz */
249         hhi_update_bits(HHI_VIID_CLK_DIV,
250                         VCLK2_DIV_MASK, (55 - 1));
251
252         /* select vid_pll for vclk2 */
253         hhi_update_bits(HHI_VIID_CLK_CNTL,
254                         VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT));
255         /* enable vclk2 gate */
256         hhi_update_bits(HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
257
258         /* select vclk_div1 for enci */
259         hhi_update_bits(HHI_VID_CLK_DIV,
260                         CTS_ENCI_SEL_MASK, (8 << CTS_ENCI_SEL_SHIFT));
261         /* select vclk_div1 for vdac */
262         hhi_update_bits(HHI_VIID_CLK_DIV,
263                         CTS_VDAC_SEL_MASK, (8 << CTS_VDAC_SEL_SHIFT));
264
265         /* release vclk2_div_reset and enable vclk2_div */
266         hhi_update_bits(HHI_VIID_CLK_DIV,
267                         VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN);
268
269         /* enable vclk2_div1 gate */
270         hhi_update_bits(HHI_VIID_CLK_CNTL,
271                         VCLK2_DIV1_EN, VCLK2_DIV1_EN);
272
273         /* reset vclk2 */
274         hhi_update_bits(HHI_VIID_CLK_CNTL,
275                         VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
276         hhi_update_bits(HHI_VIID_CLK_CNTL,
277                         VCLK2_SOFT_RESET, 0);
278
279         /* enable enci_clk */
280         hhi_update_bits(HHI_VID_CLK_CNTL2,
281                         CTS_ENCI_EN, CTS_ENCI_EN);
282         /* enable vdac_clk */
283         hhi_update_bits(HHI_VID_CLK_CNTL2,
284                         CTS_VDAC_EN, CTS_VDAC_EN);
285
286         debug("%s:%d\n", __func__, __LINE__);
287 }
288
289 enum {
290 /* PLL  O1 O2 O3 VP DV     EN TX */
291 /* 4320 /4 /4 /1 /5 /1  => /2 /2 */
292         MESON_VCLK_HDMI_ENCI_54000 = 1,
293 /* 4320 /4 /4 /1 /5 /1  => /1 /2 */
294         MESON_VCLK_HDMI_DDR_54000,
295 /* 2970 /4 /1 /1 /5 /1  => /1 /2 */
296         MESON_VCLK_HDMI_DDR_148500,
297 /* 2970 /2 /2 /2 /5 /1  => /1 /1 */
298         MESON_VCLK_HDMI_74250,
299 /* 2970 /1 /2 /2 /5 /1  => /1 /1 */
300         MESON_VCLK_HDMI_148500,
301 /* 2970 /1 /1 /1 /5 /2  => /1 /1 */
302         MESON_VCLK_HDMI_297000,
303 /* 5940 /1 /1 /2 /5 /1  => /1 /1 */
304         MESON_VCLK_HDMI_594000
305 };
306
307 struct meson_vclk_params {
308         unsigned int pll_base_freq;
309         unsigned int pll_od1;
310         unsigned int pll_od2;
311         unsigned int pll_od3;
312         unsigned int vid_pll_div;
313         unsigned int vclk_div;
314 } params[] = {
315         [MESON_VCLK_HDMI_ENCI_54000] = {
316                 .pll_base_freq = 4320000,
317                 .pll_od1 = 4,
318                 .pll_od2 = 4,
319                 .pll_od3 = 1,
320                 .vid_pll_div = VID_PLL_DIV_5,
321                 .vclk_div = 1,
322         },
323         [MESON_VCLK_HDMI_DDR_54000] = {
324                 .pll_base_freq = 4320000,
325                 .pll_od1 = 4,
326                 .pll_od2 = 4,
327                 .pll_od3 = 1,
328                 .vid_pll_div = VID_PLL_DIV_5,
329                 .vclk_div = 1,
330         },
331         [MESON_VCLK_HDMI_DDR_148500] = {
332                 .pll_base_freq = 2970000,
333                 .pll_od1 = 4,
334                 .pll_od2 = 1,
335                 .pll_od3 = 1,
336                 .vid_pll_div = VID_PLL_DIV_5,
337                 .vclk_div = 1,
338         },
339         [MESON_VCLK_HDMI_74250] = {
340                 .pll_base_freq = 2970000,
341                 .pll_od1 = 2,
342                 .pll_od2 = 2,
343                 .pll_od3 = 2,
344                 .vid_pll_div = VID_PLL_DIV_5,
345                 .vclk_div = 1,
346         },
347         [MESON_VCLK_HDMI_148500] = {
348                 .pll_base_freq = 2970000,
349                 .pll_od1 = 1,
350                 .pll_od2 = 2,
351                 .pll_od3 = 2,
352                 .vid_pll_div = VID_PLL_DIV_5,
353                 .vclk_div = 1,
354         },
355         [MESON_VCLK_HDMI_297000] = {
356                 .pll_base_freq = 2970000,
357                 .pll_od1 = 1,
358                 .pll_od2 = 1,
359                 .pll_od3 = 1,
360                 .vid_pll_div = VID_PLL_DIV_5,
361                 .vclk_div = 2,
362         },
363         [MESON_VCLK_HDMI_594000] = {
364                 .pll_base_freq = 5940000,
365                 .pll_od1 = 1,
366                 .pll_od2 = 1,
367                 .pll_od3 = 2,
368                 .vid_pll_div = VID_PLL_DIV_5,
369                 .vclk_div = 1,
370         },
371 };
372
373 static inline unsigned int pll_od_to_reg(unsigned int od)
374 {
375         switch (od) {
376         case 1:
377                 return 0;
378         case 2:
379                 return 1;
380         case 4:
381                 return 2;
382         case 8:
383                 return 3;
384         }
385
386         /* Invalid */
387         return 0;
388 }
389
390 void meson_hdmi_pll_set_params(struct meson_vpu_priv *priv, unsigned int m,
391                                unsigned int frac, unsigned int od1,
392                                unsigned int od2, unsigned int od3)
393 {
394         unsigned int val;
395
396         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
397                 hhi_write(HHI_HDMI_PLL_CNTL, 0x58000200 | m);
398                 if (frac)
399                         hhi_write(HHI_HDMI_PLL_CNTL2,
400                                   0x00004000 | frac);
401                 else
402                         hhi_write(HHI_HDMI_PLL_CNTL2,
403                                   0x00000000);
404                 hhi_write(HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
405                 hhi_write(HHI_HDMI_PLL_CNTL4, 0x801da72c);
406                 hhi_write(HHI_HDMI_PLL_CNTL5, 0x71486980);
407                 hhi_write(HHI_HDMI_PLL_CNTL6, 0x00000e55);
408
409                 /* Enable and unreset */
410                 hhi_update_bits(HHI_HDMI_PLL_CNTL,
411                                 0x7 << 28, 0x4 << 28);
412
413                 /* Poll for lock bit */
414                 readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
415                                    (val & HDMI_PLL_LOCK), 10);
416         } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
417                    meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
418                 hhi_write(HHI_HDMI_PLL_CNTL, 0x40000200 | m);
419                 hhi_write(HHI_HDMI_PLL_CNTL2, 0x800cb000 | frac);
420                 hhi_write(HHI_HDMI_PLL_CNTL3, 0x860f30c4);
421                 hhi_write(HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
422                 hhi_write(HHI_HDMI_PLL_CNTL5, 0x001fa729);
423                 hhi_write(HHI_HDMI_PLL_CNTL6, 0x01a31500);
424
425                 /* Reset PLL */
426                 hhi_update_bits(HHI_HDMI_PLL_CNTL,
427                                 HDMI_PLL_RESET, HDMI_PLL_RESET);
428                 hhi_update_bits(HHI_HDMI_PLL_CNTL,
429                                 HDMI_PLL_RESET, 0);
430
431                 /* Poll for lock bit */
432                 readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
433                                    (val & HDMI_PLL_LOCK), 10);
434         }
435
436         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
437                 hhi_update_bits(HHI_HDMI_PLL_CNTL2,
438                                 3 << 16, pll_od_to_reg(od1) << 16);
439         else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
440                  meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
441                 hhi_update_bits(HHI_HDMI_PLL_CNTL3,
442                                 3 << 21, pll_od_to_reg(od1) << 21);
443
444         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
445                 hhi_update_bits(HHI_HDMI_PLL_CNTL2,
446                                 3 << 22, pll_od_to_reg(od2) << 22);
447         else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
448                  meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
449                 hhi_update_bits(HHI_HDMI_PLL_CNTL3,
450                                 3 << 23, pll_od_to_reg(od2) << 23);
451
452         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
453                 hhi_update_bits(HHI_HDMI_PLL_CNTL2,
454                                 3 << 18, pll_od_to_reg(od3) << 18);
455         else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
456                  meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
457                 hhi_update_bits(HHI_HDMI_PLL_CNTL3,
458                                 3 << 19, pll_od_to_reg(od3) << 19);
459 }
460
461 #define XTAL_FREQ 24000
462
463 static unsigned int meson_hdmi_pll_get_m(struct meson_vpu_priv *priv,
464                                          unsigned int pll_freq)
465 {
466         /* The GXBB PLL has a /2 pre-multiplier */
467         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
468                 pll_freq /= 2;
469
470         return pll_freq / XTAL_FREQ;
471 }
472
473 #define HDMI_FRAC_MAX_GXBB      4096
474 #define HDMI_FRAC_MAX_GXL       1024
475
476 static unsigned int meson_hdmi_pll_get_frac(struct meson_vpu_priv *priv,
477                                             unsigned int m,
478                                             unsigned int pll_freq)
479 {
480         unsigned int parent_freq = XTAL_FREQ;
481         unsigned int frac_max = HDMI_FRAC_MAX_GXL;
482         unsigned int frac_m;
483         unsigned int frac;
484
485         /* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */
486         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
487                 frac_max = HDMI_FRAC_MAX_GXBB;
488                 parent_freq *= 2;
489         }
490
491         /* We can have a perfect match !*/
492         if (pll_freq / m == parent_freq &&
493             pll_freq % m == 0)
494                 return 0;
495
496         frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq);
497         frac_m = m * frac_max;
498         if (frac_m > frac)
499                 return frac_max;
500         frac -= frac_m;
501
502         return min((u16)frac, (u16)(frac_max - 1));
503 }
504
505 static bool meson_hdmi_pll_validate_params(struct meson_vpu_priv *priv,
506                                            unsigned int m,
507                                            unsigned int frac)
508 {
509         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
510                 /* Empiric supported min/max dividers */
511                 if (m < 53 || m > 123)
512                         return false;
513                 if (frac >= HDMI_FRAC_MAX_GXBB)
514                         return false;
515         } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
516                    meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
517                 /* Empiric supported min/max dividers */
518                 if (m < 106 || m > 247)
519                         return false;
520                 if (frac >= HDMI_FRAC_MAX_GXL)
521                         return false;
522         }
523
524         return true;
525 }
526
527 static bool meson_hdmi_pll_find_params(struct meson_vpu_priv *priv,
528                                        unsigned int freq,
529                                        unsigned int *m,
530                                        unsigned int *frac,
531                                        unsigned int *od)
532 {
533         /* Cycle from /16 to /2 */
534         for (*od = 16 ; *od > 1 ; *od >>= 1) {
535                 *m = meson_hdmi_pll_get_m(priv, freq * *od);
536                 if (!*m)
537                         continue;
538                 *frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od);
539
540                 debug("PLL params for %dkHz: m=%x frac=%x od=%d\n",
541                       freq, *m, *frac, *od);
542
543                 if (meson_hdmi_pll_validate_params(priv, *m, *frac))
544                         return true;
545         }
546
547         return false;
548 }
549
550 /* pll_freq is the frequency after the OD dividers */
551 bool meson_vclk_dmt_supported_freq(struct meson_vpu_priv *priv,
552                                    unsigned int freq)
553 {
554         unsigned int od, m, frac;
555
556         /* In DMT mode, path after PLL is always /10 */
557         freq *= 10;
558
559         if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od))
560                 return true;
561
562         return false;
563 }
564
565 /* pll_freq is the frequency after the OD dividers */
566 static void meson_hdmi_pll_generic_set(struct meson_vpu_priv *priv,
567                                        unsigned int pll_freq)
568 {
569         unsigned int od, m, frac, od1, od2, od3;
570
571         if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) {
572                 od3 = 1;
573                 if (od < 4) {
574                         od1 = 2;
575                         od2 = 1;
576                 } else {
577                         od2 = od / 4;
578                         od1 = od / od2;
579                 }
580
581                 debug("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n",
582                       pll_freq, m, frac, od1, od2, od3);
583
584                 meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
585
586                 return;
587         }
588
589         printf("Fatal, unable to find parameters for PLL freq %d\n",
590                pll_freq);
591 }
592
593 static void
594 meson_vclk_set(struct meson_vpu_priv *priv, unsigned int pll_base_freq,
595                unsigned int od1, unsigned int od2, unsigned int od3,
596                unsigned int vid_pll_div, unsigned int vclk_div,
597                unsigned int hdmi_tx_div, unsigned int venc_div,
598                bool hdmi_use_enci)
599 {
600         /* Set HDMI-TX sys clock */
601         hhi_update_bits(HHI_HDMI_CLK_CNTL,
602                         CTS_HDMI_SYS_SEL_MASK, 0);
603         hhi_update_bits(HHI_HDMI_CLK_CNTL,
604                         CTS_HDMI_SYS_DIV_MASK, 0);
605         hhi_update_bits(HHI_HDMI_CLK_CNTL,
606                         CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
607
608         /* Set HDMI PLL rate */
609         if (!od1 && !od2 && !od3) {
610                 meson_hdmi_pll_generic_set(priv, pll_base_freq);
611         } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
612                 switch (pll_base_freq) {
613                 case 2970000:
614                         meson_hdmi_pll_set_params(priv, 0x3d, 0xe00,
615                                                   od1, od2, od3);
616                         break;
617                 case 4320000:
618                         meson_hdmi_pll_set_params(priv, 0x5a, 0,
619                                                   od1, od2, od3);
620                         break;
621                 case 5940000:
622                         meson_hdmi_pll_set_params(priv, 0x7b, 0xc00,
623                                                   od1, od2, od3);
624                         break;
625                 }
626         } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
627                    meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
628                 switch (pll_base_freq) {
629                 case 2970000:
630                         meson_hdmi_pll_set_params(priv, 0x7b, 0x300,
631                                                   od1, od2, od3);
632                         break;
633                 case 4320000:
634                         meson_hdmi_pll_set_params(priv, 0xb4, 0,
635                                                   od1, od2, od3);
636                         break;
637                 case 5940000:
638                         meson_hdmi_pll_set_params(priv, 0xf7, 0x200,
639                                                   od1, od2, od3);
640                         break;
641                 }
642         }
643
644         /* Setup vid_pll divider */
645         meson_vid_pll_set(priv, vid_pll_div);
646
647         /* Set VCLK div */
648         hhi_update_bits(HHI_VID_CLK_CNTL,
649                         VCLK_SEL_MASK, 0);
650         hhi_update_bits(HHI_VID_CLK_DIV,
651                         VCLK_DIV_MASK, vclk_div - 1);
652
653         /* Set HDMI-TX source */
654         switch (hdmi_tx_div) {
655         case 1:
656                 /* enable vclk_div1 gate */
657                 hhi_update_bits(HHI_VID_CLK_CNTL,
658                                 VCLK_DIV1_EN, VCLK_DIV1_EN);
659
660                 /* select vclk_div1 for HDMI-TX */
661                 hhi_update_bits(HHI_HDMI_CLK_CNTL,
662                                 HDMI_TX_PIXEL_SEL_MASK, 0);
663                 break;
664         case 2:
665                 /* enable vclk_div2 gate */
666                 hhi_update_bits(HHI_VID_CLK_CNTL,
667                                 VCLK_DIV2_EN, VCLK_DIV2_EN);
668
669                 /* select vclk_div2 for HDMI-TX */
670                 hhi_update_bits(HHI_HDMI_CLK_CNTL,
671                                 HDMI_TX_PIXEL_SEL_MASK,
672                                 1 << HDMI_TX_PIXEL_SEL_SHIFT);
673                 break;
674         case 4:
675                 /* enable vclk_div4 gate */
676                 hhi_update_bits(HHI_VID_CLK_CNTL,
677                                 VCLK_DIV4_EN, VCLK_DIV4_EN);
678
679                 /* select vclk_div4 for HDMI-TX */
680                 hhi_update_bits(HHI_HDMI_CLK_CNTL,
681                                 HDMI_TX_PIXEL_SEL_MASK,
682                                 2 << HDMI_TX_PIXEL_SEL_SHIFT);
683                 break;
684         case 6:
685                 /* enable vclk_div6 gate */
686                 hhi_update_bits(HHI_VID_CLK_CNTL,
687                                 VCLK_DIV6_EN, VCLK_DIV6_EN);
688
689                 /* select vclk_div6 for HDMI-TX */
690                 hhi_update_bits(HHI_HDMI_CLK_CNTL,
691                                 HDMI_TX_PIXEL_SEL_MASK,
692                                 3 << HDMI_TX_PIXEL_SEL_SHIFT);
693                 break;
694         case 12:
695                 /* enable vclk_div12 gate */
696                 hhi_update_bits(HHI_VID_CLK_CNTL,
697                                 VCLK_DIV12_EN, VCLK_DIV12_EN);
698
699                 /* select vclk_div12 for HDMI-TX */
700                 hhi_update_bits(HHI_HDMI_CLK_CNTL,
701                                 HDMI_TX_PIXEL_SEL_MASK,
702                                 4 << HDMI_TX_PIXEL_SEL_SHIFT);
703                 break;
704         }
705         hhi_update_bits(HHI_VID_CLK_CNTL2,
706                         HDMI_TX_PIXEL_EN, HDMI_TX_PIXEL_EN);
707
708         /* Set ENCI/ENCP Source */
709         switch (venc_div) {
710         case 1:
711                 /* enable vclk_div1 gate */
712                 hhi_update_bits(HHI_VID_CLK_CNTL,
713                                 VCLK_DIV1_EN, VCLK_DIV1_EN);
714
715                 if (hdmi_use_enci)
716                         /* select vclk_div1 for enci */
717                         hhi_update_bits(HHI_VID_CLK_DIV,
718                                         CTS_ENCI_SEL_MASK, 0);
719                 else
720                         /* select vclk_div1 for encp */
721                         hhi_update_bits(HHI_VID_CLK_DIV,
722                                         CTS_ENCP_SEL_MASK, 0);
723                 break;
724         case 2:
725                 /* enable vclk_div2 gate */
726                 hhi_update_bits(HHI_VID_CLK_CNTL,
727                                 VCLK_DIV2_EN, VCLK_DIV2_EN);
728
729                 if (hdmi_use_enci)
730                         /* select vclk_div2 for enci */
731                         hhi_update_bits(HHI_VID_CLK_DIV,
732                                         CTS_ENCI_SEL_MASK,
733                                         1 << CTS_ENCI_SEL_SHIFT);
734                 else
735                         /* select vclk_div2 for encp */
736                         hhi_update_bits(HHI_VID_CLK_DIV,
737                                         CTS_ENCP_SEL_MASK,
738                                         1 << CTS_ENCP_SEL_SHIFT);
739                 break;
740         case 4:
741                 /* enable vclk_div4 gate */
742                 hhi_update_bits(HHI_VID_CLK_CNTL,
743                                 VCLK_DIV4_EN, VCLK_DIV4_EN);
744
745                 if (hdmi_use_enci)
746                         /* select vclk_div4 for enci */
747                         hhi_update_bits(HHI_VID_CLK_DIV,
748                                         CTS_ENCI_SEL_MASK,
749                                         2 << CTS_ENCI_SEL_SHIFT);
750                 else
751                         /* select vclk_div4 for encp */
752                         hhi_update_bits(HHI_VID_CLK_DIV,
753                                         CTS_ENCP_SEL_MASK,
754                                         2 << CTS_ENCP_SEL_SHIFT);
755                 break;
756         case 6:
757                 /* enable vclk_div6 gate */
758                 hhi_update_bits(HHI_VID_CLK_CNTL,
759                                 VCLK_DIV6_EN, VCLK_DIV6_EN);
760
761                 if (hdmi_use_enci)
762                         /* select vclk_div6 for enci */
763                         hhi_update_bits(HHI_VID_CLK_DIV,
764                                         CTS_ENCI_SEL_MASK,
765                                         3 << CTS_ENCI_SEL_SHIFT);
766                 else
767                         /* select vclk_div6 for encp */
768                         hhi_update_bits(HHI_VID_CLK_DIV,
769                                         CTS_ENCP_SEL_MASK,
770                                         3 << CTS_ENCP_SEL_SHIFT);
771                 break;
772         case 12:
773                 /* enable vclk_div12 gate */
774                 hhi_update_bits(HHI_VID_CLK_CNTL,
775                                 VCLK_DIV12_EN, VCLK_DIV12_EN);
776
777                 if (hdmi_use_enci)
778                         /* select vclk_div12 for enci */
779                         hhi_update_bits(HHI_VID_CLK_DIV,
780                                         CTS_ENCI_SEL_MASK,
781                                         4 << CTS_ENCI_SEL_SHIFT);
782                 else
783                         /* select vclk_div12 for encp */
784                         hhi_update_bits(HHI_VID_CLK_DIV,
785                                         CTS_ENCP_SEL_MASK,
786                                         4 << CTS_ENCP_SEL_SHIFT);
787                 break;
788         }
789
790         if (hdmi_use_enci)
791                 /* Enable ENCI clock gate */
792                 hhi_update_bits(HHI_VID_CLK_CNTL2,
793                                 CTS_ENCI_EN, CTS_ENCI_EN);
794         else
795                 /* Enable ENCP clock gate */
796                 hhi_update_bits(HHI_VID_CLK_CNTL2,
797                                 CTS_ENCP_EN, CTS_ENCP_EN);
798
799         hhi_update_bits(HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
800 }
801
802 static void meson_vclk_setup(struct meson_vpu_priv *priv, unsigned int target,
803                              unsigned int vclk_freq, unsigned int venc_freq,
804                              unsigned int dac_freq, bool hdmi_use_enci)
805 {
806         unsigned int freq;
807         unsigned int hdmi_tx_div;
808         unsigned int venc_div;
809
810         if (target == MESON_VCLK_TARGET_CVBS) {
811                 meson_venci_cvbs_clock_config(priv);
812                 return;
813         } else if (target == MESON_VCLK_TARGET_DMT) {
814                 /* The DMT clock path is fixed after the PLL:
815                  * - automatic PLL freq + OD management
816                  * - vid_pll_div = VID_PLL_DIV_5
817                  * - vclk_div = 2
818                  * - hdmi_tx_div = 1
819                  * - venc_div = 1
820                  * - encp encoder
821                  */
822                 meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0,
823                                VID_PLL_DIV_5, 2, 1, 1, false);
824
825                 return;
826         }
827
828         hdmi_tx_div = vclk_freq / dac_freq;
829
830         if (hdmi_tx_div == 0) {
831                 printf("Fatal Error, invalid HDMI-TX freq %d\n",
832                        dac_freq);
833                 return;
834         }
835
836         venc_div = vclk_freq / venc_freq;
837
838         if (venc_div == 0) {
839                 printf("Fatal Error, invalid HDMI venc freq %d\n",
840                        venc_freq);
841                 return;
842         }
843
844         switch (vclk_freq) {
845         case 54000:
846                 if (hdmi_use_enci)
847                         freq = MESON_VCLK_HDMI_ENCI_54000;
848                 else
849                         freq = MESON_VCLK_HDMI_DDR_54000;
850                 break;
851         case 74250:
852                 freq = MESON_VCLK_HDMI_74250;
853                 break;
854         case 148500:
855                 if (dac_freq != 148500)
856                         freq = MESON_VCLK_HDMI_DDR_148500;
857                 else
858                         freq = MESON_VCLK_HDMI_148500;
859                 break;
860         case 297000:
861                 freq = MESON_VCLK_HDMI_297000;
862                 break;
863         case 594000:
864                 freq = MESON_VCLK_HDMI_594000;
865                 break;
866         default:
867                 printf("Fatal Error, invalid HDMI vclk freq %d\n",
868                        vclk_freq);
869                 return;
870         }
871
872         meson_vclk_set(priv, params[freq].pll_base_freq,
873                        params[freq].pll_od1, params[freq].pll_od2,
874                        params[freq].pll_od3, params[freq].vid_pll_div,
875                        params[freq].vclk_div, hdmi_tx_div, venc_div,
876                        hdmi_use_enci);
877 }
878
879 void meson_vpu_setup_vclk(struct udevice *dev,
880                           const struct display_timing *mode, bool is_cvbs)
881 {
882         struct meson_vpu_priv *priv = dev_get_priv(dev);
883         unsigned int vclk_freq;
884
885         if (is_cvbs)
886                 return meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS,
887                                         0, 0, 0, false);
888
889         vclk_freq = mode->pixelclock.typ / 1000;
890
891         return meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT,
892                                 vclk_freq, vclk_freq, vclk_freq, false);
893 }