1
2
3
4
5
6
7
8
9#include <common.h>
10#include <dm.h>
11#include <edid.h>
12#include <linux/bitops.h>
13#include "meson_vpu.h"
14#include <log.h>
15#include <linux/iopoll.h>
16#include <linux/math64.h>
17
18#define writel_bits(mask, val, addr) \
19 writel((readl(addr) & ~(mask)) | (val), addr)
20
21enum {
22 MESON_VCLK_TARGET_CVBS = 0,
23 MESON_VCLK_TARGET_HDMI = 1,
24 MESON_VCLK_TARGET_DMT = 2,
25};
26
27
28#define HHI_VID_PLL_CLK_DIV 0x1a0
29#define VID_PLL_EN BIT(19)
30#define VID_PLL_BYPASS BIT(18)
31#define VID_PLL_PRESET BIT(15)
32#define HHI_VIID_CLK_DIV 0x128
33#define VCLK2_DIV_MASK 0xff
34#define VCLK2_DIV_EN BIT(16)
35#define VCLK2_DIV_RESET BIT(17)
36#define CTS_VDAC_SEL_MASK (0xf << 28)
37#define CTS_VDAC_SEL_SHIFT 28
38#define HHI_VIID_CLK_CNTL 0x12c
39#define VCLK2_EN BIT(19)
40#define VCLK2_SEL_MASK (0x7 << 16)
41#define VCLK2_SEL_SHIFT 16
42#define VCLK2_SOFT_RESET BIT(15)
43#define VCLK2_DIV1_EN BIT(0)
44#define HHI_VID_CLK_DIV 0x164
45#define VCLK_DIV_MASK 0xff
46#define VCLK_DIV_EN BIT(16)
47#define VCLK_DIV_RESET BIT(17)
48#define CTS_ENCP_SEL_MASK (0xf << 24)
49#define CTS_ENCP_SEL_SHIFT 24
50#define CTS_ENCI_SEL_MASK (0xf << 28)
51#define CTS_ENCI_SEL_SHIFT 28
52#define HHI_VID_CLK_CNTL 0x17c
53#define VCLK_EN BIT(19)
54#define VCLK_SEL_MASK (0x7 << 16)
55#define VCLK_SEL_SHIFT 16
56#define VCLK_SOFT_RESET BIT(15)
57#define VCLK_DIV1_EN BIT(0)
58#define VCLK_DIV2_EN BIT(1)
59#define VCLK_DIV4_EN BIT(2)
60#define VCLK_DIV6_EN BIT(3)
61#define VCLK_DIV12_EN BIT(4)
62#define HHI_VID_CLK_CNTL2 0x194
63#define CTS_ENCI_EN BIT(0)
64#define CTS_ENCP_EN BIT(2)
65#define CTS_VDAC_EN BIT(4)
66#define HDMI_TX_PIXEL_EN BIT(5)
67#define HHI_HDMI_CLK_CNTL 0x1cc
68#define HDMI_TX_PIXEL_SEL_MASK (0xf << 16)
69#define HDMI_TX_PIXEL_SEL_SHIFT 16
70#define CTS_HDMI_SYS_SEL_MASK (0x7 << 9)
71#define CTS_HDMI_SYS_DIV_MASK (0x7f)
72#define CTS_HDMI_SYS_EN BIT(8)
73
74#define HHI_HDMI_PLL_CNTL 0x320
75#define HHI_HDMI_PLL_CNTL_EN BIT(30)
76#define HHI_HDMI_PLL_CNTL2 0x324
77#define HHI_HDMI_PLL_CNTL3 0x328
78#define HHI_HDMI_PLL_CNTL4 0x32C
79#define HHI_HDMI_PLL_CNTL5 0x330
80#define HHI_HDMI_PLL_CNTL6 0x334
81#define HHI_HDMI_PLL_CNTL7 0x338
82
83#define HDMI_PLL_RESET BIT(28)
84#define HDMI_PLL_RESET_G12A BIT(29)
85#define HDMI_PLL_LOCK BIT(31)
86#define HDMI_PLL_LOCK_G12A (3 << 30)
87
88#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001)
89
90
91enum {
92 VID_PLL_DIV_1 = 0,
93 VID_PLL_DIV_2,
94 VID_PLL_DIV_2p5,
95 VID_PLL_DIV_3,
96 VID_PLL_DIV_3p5,
97 VID_PLL_DIV_3p75,
98 VID_PLL_DIV_4,
99 VID_PLL_DIV_5,
100 VID_PLL_DIV_6,
101 VID_PLL_DIV_6p25,
102 VID_PLL_DIV_7,
103 VID_PLL_DIV_7p5,
104 VID_PLL_DIV_12,
105 VID_PLL_DIV_14,
106 VID_PLL_DIV_15,
107};
108
109void meson_vid_pll_set(struct meson_vpu_priv *priv, unsigned int div)
110{
111 unsigned int shift_val = 0;
112 unsigned int shift_sel = 0;
113
114
115 hhi_update_bits(HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0);
116 hhi_update_bits(HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0);
117
118 switch (div) {
119 case VID_PLL_DIV_2:
120 shift_val = 0x0aaa;
121 shift_sel = 0;
122 break;
123 case VID_PLL_DIV_2p5:
124 shift_val = 0x5294;
125 shift_sel = 2;
126 break;
127 case VID_PLL_DIV_3:
128 shift_val = 0x0db6;
129 shift_sel = 0;
130 break;
131 case VID_PLL_DIV_3p5:
132 shift_val = 0x36cc;
133 shift_sel = 1;
134 break;
135 case VID_PLL_DIV_3p75:
136 shift_val = 0x6666;
137 shift_sel = 2;
138 break;
139 case VID_PLL_DIV_4:
140 shift_val = 0x0ccc;
141 shift_sel = 0;
142 break;
143 case VID_PLL_DIV_5:
144 shift_val = 0x739c;
145 shift_sel = 2;
146 break;
147 case VID_PLL_DIV_6:
148 shift_val = 0x0e38;
149 shift_sel = 0;
150 break;
151 case VID_PLL_DIV_6p25:
152 shift_val = 0x0000;
153 shift_sel = 3;
154 break;
155 case VID_PLL_DIV_7:
156 shift_val = 0x3c78;
157 shift_sel = 1;
158 break;
159 case VID_PLL_DIV_7p5:
160 shift_val = 0x78f0;
161 shift_sel = 2;
162 break;
163 case VID_PLL_DIV_12:
164 shift_val = 0x0fc0;
165 shift_sel = 0;
166 break;
167 case VID_PLL_DIV_14:
168 shift_val = 0x3f80;
169 shift_sel = 1;
170 break;
171 case VID_PLL_DIV_15:
172 shift_val = 0x7f80;
173 shift_sel = 2;
174 break;
175 }
176
177 if (div == VID_PLL_DIV_1) {
178
179 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
180 VID_PLL_BYPASS, VID_PLL_BYPASS);
181 } else {
182
183 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
184 VID_PLL_BYPASS, 0);
185
186 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
187 3 << 16, 0);
188 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
189 VID_PLL_PRESET, 0);
190 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
191 0x7fff, 0);
192
193
194 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
195 3 << 16, shift_sel << 16);
196 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
197 VID_PLL_PRESET, VID_PLL_PRESET);
198 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
199 0x7fff, shift_val);
200
201 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
202 VID_PLL_PRESET, 0);
203 }
204
205
206 hhi_update_bits(HHI_VID_PLL_CLK_DIV,
207 VID_PLL_EN, VID_PLL_EN);
208}
209
210
211
212
213
214
215static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv)
216{
217 unsigned int val;
218
219
220 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
221 hhi_write(HHI_HDMI_PLL_CNTL, 0x5800023d);
222 hhi_write(HHI_HDMI_PLL_CNTL2, 0x00404e00);
223 hhi_write(HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
224 hhi_write(HHI_HDMI_PLL_CNTL4, 0x801da72c);
225 hhi_write(HHI_HDMI_PLL_CNTL5, 0x71486980);
226 hhi_write(HHI_HDMI_PLL_CNTL6, 0x00000e55);
227 hhi_write(HHI_HDMI_PLL_CNTL, 0x4800023d);
228
229
230 readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
231 (val & HDMI_PLL_LOCK), 10);
232 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
233 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
234 hhi_write(HHI_HDMI_PLL_CNTL, 0x4000027b);
235 hhi_write(HHI_HDMI_PLL_CNTL2, 0x800cb300);
236 hhi_write(HHI_HDMI_PLL_CNTL3, 0xa6212844);
237 hhi_write(HHI_HDMI_PLL_CNTL4, 0x0c4d000c);
238 hhi_write(HHI_HDMI_PLL_CNTL5, 0x001fa729);
239 hhi_write(HHI_HDMI_PLL_CNTL6, 0x01a31500);
240
241
242 hhi_update_bits(HHI_HDMI_PLL_CNTL,
243 HDMI_PLL_RESET, HDMI_PLL_RESET);
244 hhi_update_bits(HHI_HDMI_PLL_CNTL,
245 HDMI_PLL_RESET, 0);
246
247
248 readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
249 (val & HDMI_PLL_LOCK), 10);
250 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
251 hhi_write(HHI_HDMI_PLL_CNTL, 0x1a0504f7);
252 hhi_write(HHI_HDMI_PLL_CNTL2, 0x00010000);
253 hhi_write(HHI_HDMI_PLL_CNTL3, 0x00000000);
254 hhi_write(HHI_HDMI_PLL_CNTL4, 0x6a28dc00);
255 hhi_write(HHI_HDMI_PLL_CNTL5, 0x65771290);
256 hhi_write(HHI_HDMI_PLL_CNTL6, 0x39272000);
257 hhi_write(HHI_HDMI_PLL_CNTL7, 0x56540000);
258 hhi_write(HHI_HDMI_PLL_CNTL, 0x3a0504f7);
259 hhi_write(HHI_HDMI_PLL_CNTL, 0x1a0504f7);
260
261
262 readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
263 ((val & HDMI_PLL_LOCK_G12A) == HDMI_PLL_LOCK_G12A),
264 10);
265 }
266
267
268 hhi_update_bits(HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
269
270
271 meson_vid_pll_set(priv, VID_PLL_DIV_1);
272
273
274 hhi_update_bits(HHI_VIID_CLK_DIV,
275 VCLK2_DIV_MASK, (55 - 1));
276
277
278 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
279 hhi_update_bits(HHI_VIID_CLK_CNTL,
280 VCLK2_SEL_MASK, (0 << VCLK2_SEL_SHIFT));
281 else
282 hhi_update_bits(HHI_VIID_CLK_CNTL,
283 VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT));
284
285
286 hhi_update_bits(HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
287
288
289 hhi_update_bits(HHI_VID_CLK_DIV,
290 CTS_ENCI_SEL_MASK, (8 << CTS_ENCI_SEL_SHIFT));
291
292 hhi_update_bits(HHI_VIID_CLK_DIV,
293 CTS_VDAC_SEL_MASK, (8 << CTS_VDAC_SEL_SHIFT));
294
295
296 hhi_update_bits(HHI_VIID_CLK_DIV,
297 VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN);
298
299
300 hhi_update_bits(HHI_VIID_CLK_CNTL,
301 VCLK2_DIV1_EN, VCLK2_DIV1_EN);
302
303
304 hhi_update_bits(HHI_VIID_CLK_CNTL,
305 VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
306 hhi_update_bits(HHI_VIID_CLK_CNTL,
307 VCLK2_SOFT_RESET, 0);
308
309
310 hhi_update_bits(HHI_VID_CLK_CNTL2,
311 CTS_ENCI_EN, CTS_ENCI_EN);
312
313 hhi_update_bits(HHI_VID_CLK_CNTL2,
314 CTS_VDAC_EN, CTS_VDAC_EN);
315}
316
317enum {
318
319
320 MESON_VCLK_HDMI_ENCI_54000 = 0,
321
322 MESON_VCLK_HDMI_DDR_54000,
323
324 MESON_VCLK_HDMI_DDR_148500,
325
326 MESON_VCLK_HDMI_74250,
327
328 MESON_VCLK_HDMI_148500,
329
330 MESON_VCLK_HDMI_297000,
331
332 MESON_VCLK_HDMI_594000
333};
334
335struct meson_vclk_params {
336 unsigned int pixel_freq;
337 unsigned int pll_base_freq;
338 unsigned int pll_od1;
339 unsigned int pll_od2;
340 unsigned int pll_od3;
341 unsigned int vid_pll_div;
342 unsigned int vclk_div;
343} params[] = {
344 [MESON_VCLK_HDMI_ENCI_54000] = {
345 .pixel_freq = 54000,
346 .pll_base_freq = 4320000,
347 .pll_od1 = 4,
348 .pll_od2 = 4,
349 .pll_od3 = 1,
350 .vid_pll_div = VID_PLL_DIV_5,
351 .vclk_div = 1,
352 },
353 [MESON_VCLK_HDMI_DDR_54000] = {
354 .pixel_freq = 54000,
355 .pll_base_freq = 4320000,
356 .pll_od1 = 4,
357 .pll_od2 = 4,
358 .pll_od3 = 1,
359 .vid_pll_div = VID_PLL_DIV_5,
360 .vclk_div = 1,
361 },
362 [MESON_VCLK_HDMI_DDR_148500] = {
363 .pixel_freq = 148500,
364 .pll_base_freq = 2970000,
365 .pll_od1 = 4,
366 .pll_od2 = 1,
367 .pll_od3 = 1,
368 .vid_pll_div = VID_PLL_DIV_5,
369 .vclk_div = 1,
370 },
371 [MESON_VCLK_HDMI_74250] = {
372 .pixel_freq = 74250,
373 .pll_base_freq = 2970000,
374 .pll_od1 = 2,
375 .pll_od2 = 2,
376 .pll_od3 = 2,
377 .vid_pll_div = VID_PLL_DIV_5,
378 .vclk_div = 1,
379 },
380 [MESON_VCLK_HDMI_148500] = {
381 .pixel_freq = 148500,
382 .pll_base_freq = 2970000,
383 .pll_od1 = 1,
384 .pll_od2 = 2,
385 .pll_od3 = 2,
386 .vid_pll_div = VID_PLL_DIV_5,
387 .vclk_div = 1,
388 },
389 [MESON_VCLK_HDMI_297000] = {
390 .pixel_freq = 297000,
391 .pll_base_freq = 5940000,
392 .pll_od1 = 2,
393 .pll_od2 = 1,
394 .pll_od3 = 1,
395 .vid_pll_div = VID_PLL_DIV_5,
396 .vclk_div = 2,
397 },
398 [MESON_VCLK_HDMI_594000] = {
399 .pixel_freq = 594000,
400 .pll_base_freq = 5940000,
401 .pll_od1 = 1,
402 .pll_od2 = 1,
403 .pll_od3 = 2,
404 .vid_pll_div = VID_PLL_DIV_5,
405 .vclk_div = 1,
406 },
407 { },
408};
409
410static inline unsigned int pll_od_to_reg(unsigned int od)
411{
412 switch (od) {
413 case 1:
414 return 0;
415 case 2:
416 return 1;
417 case 4:
418 return 2;
419 case 8:
420 return 3;
421 }
422
423
424 return 0;
425}
426
427void meson_hdmi_pll_set_params(struct meson_vpu_priv *priv, unsigned int m,
428 unsigned int frac, unsigned int od1,
429 unsigned int od2, unsigned int od3)
430{
431 unsigned int val;
432
433 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
434 hhi_write(HHI_HDMI_PLL_CNTL, 0x58000200 | m);
435 if (frac)
436 hhi_write(HHI_HDMI_PLL_CNTL2,
437 0x00004000 | frac);
438 else
439 hhi_write(HHI_HDMI_PLL_CNTL2,
440 0x00000000);
441 hhi_write(HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
442 hhi_write(HHI_HDMI_PLL_CNTL4, 0x801da72c);
443 hhi_write(HHI_HDMI_PLL_CNTL5, 0x71486980);
444 hhi_write(HHI_HDMI_PLL_CNTL6, 0x00000e55);
445
446
447 hhi_update_bits(HHI_HDMI_PLL_CNTL,
448 0x7 << 28, 0x4 << 28);
449
450
451 readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
452 (val & HDMI_PLL_LOCK), 10);
453 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
454 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
455 hhi_write(HHI_HDMI_PLL_CNTL, 0x40000200 | m);
456 hhi_write(HHI_HDMI_PLL_CNTL2, 0x800cb000 | frac);
457 hhi_write(HHI_HDMI_PLL_CNTL3, 0x860f30c4);
458 hhi_write(HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
459 hhi_write(HHI_HDMI_PLL_CNTL5, 0x001fa729);
460 hhi_write(HHI_HDMI_PLL_CNTL6, 0x01a31500);
461
462
463 hhi_update_bits(HHI_HDMI_PLL_CNTL,
464 HDMI_PLL_RESET, HDMI_PLL_RESET);
465 hhi_update_bits(HHI_HDMI_PLL_CNTL,
466 HDMI_PLL_RESET, 0);
467
468
469 readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
470 (val & HDMI_PLL_LOCK), 10);
471 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
472 hhi_write(HHI_HDMI_PLL_CNTL, 0x0b3a0400 | m);
473
474
475 hhi_update_bits(HHI_HDMI_PLL_CNTL, 0x3 << 28, 0x3 << 28);
476
477 hhi_write(HHI_HDMI_PLL_CNTL2, frac);
478 hhi_write(HHI_HDMI_PLL_CNTL3, 0x00000000);
479
480
481 if (m >= 0xf7) {
482 if (frac < 0x10000) {
483 hhi_write(HHI_HDMI_PLL_CNTL4, 0x6a685c00);
484 hhi_write(HHI_HDMI_PLL_CNTL5, 0x11551293);
485 } else {
486 hhi_write(HHI_HDMI_PLL_CNTL4, 0xea68dc00);
487 hhi_write(HHI_HDMI_PLL_CNTL5, 0x65771290);
488 }
489 hhi_write(HHI_HDMI_PLL_CNTL6, 0x39272000);
490 hhi_write(HHI_HDMI_PLL_CNTL7, 0x55540000);
491 } else {
492 hhi_write(HHI_HDMI_PLL_CNTL4, 0x0a691c00);
493 hhi_write(HHI_HDMI_PLL_CNTL5, 0x33771290);
494 hhi_write(HHI_HDMI_PLL_CNTL6, 0x39270000);
495 hhi_write(HHI_HDMI_PLL_CNTL7, 0x50540000);
496 }
497
498 do {
499
500 hhi_update_bits(HHI_HDMI_PLL_CNTL,
501 HDMI_PLL_RESET_G12A,
502 HDMI_PLL_RESET_G12A);
503
504
505 hhi_update_bits(HHI_HDMI_PLL_CNTL,
506 HDMI_PLL_RESET_G12A, 0);
507
508
509 if (!readl_poll_timeout(
510 priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
511 ((val & HDMI_PLL_LOCK_G12A)
512 == HDMI_PLL_LOCK_G12A), 100))
513 break;
514 } while (1);
515 }
516
517 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
518 hhi_update_bits(HHI_HDMI_PLL_CNTL2,
519 3 << 16, pll_od_to_reg(od1) << 16);
520 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
521 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
522 hhi_update_bits(HHI_HDMI_PLL_CNTL3,
523 3 << 21, pll_od_to_reg(od1) << 21);
524 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
525 hhi_update_bits(HHI_HDMI_PLL_CNTL,
526 3 << 16, pll_od_to_reg(od1) << 16);
527
528 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
529 hhi_update_bits(HHI_HDMI_PLL_CNTL2,
530 3 << 22, pll_od_to_reg(od2) << 22);
531 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
532 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
533 hhi_update_bits(HHI_HDMI_PLL_CNTL3,
534 3 << 23, pll_od_to_reg(od2) << 23);
535 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
536 hhi_update_bits(HHI_HDMI_PLL_CNTL,
537 3 << 18, pll_od_to_reg(od2) << 18);
538
539 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
540 hhi_update_bits(HHI_HDMI_PLL_CNTL2,
541 3 << 18, pll_od_to_reg(od3) << 18);
542 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
543 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
544 hhi_update_bits(HHI_HDMI_PLL_CNTL3,
545 3 << 19, pll_od_to_reg(od3) << 19);
546 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
547 hhi_update_bits(HHI_HDMI_PLL_CNTL,
548 3 << 20, pll_od_to_reg(od3) << 20);
549}
550
551#define XTAL_FREQ 24000
552
553static unsigned int meson_hdmi_pll_get_m(struct meson_vpu_priv *priv,
554 unsigned int pll_freq)
555{
556
557 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
558 pll_freq /= 2;
559
560 return pll_freq / XTAL_FREQ;
561}
562
563#define HDMI_FRAC_MAX_GXBB 4096
564#define HDMI_FRAC_MAX_GXL 1024
565#define HDMI_FRAC_MAX_G12A 131072
566
567static unsigned int meson_hdmi_pll_get_frac(struct meson_vpu_priv *priv,
568 unsigned int m,
569 unsigned int pll_freq)
570{
571 unsigned int parent_freq = XTAL_FREQ;
572 unsigned int frac_max = HDMI_FRAC_MAX_GXL;
573 unsigned int frac_m;
574 unsigned int frac;
575
576
577 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
578 frac_max = HDMI_FRAC_MAX_GXBB;
579 parent_freq *= 2;
580 }
581
582 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
583 frac_max = HDMI_FRAC_MAX_G12A;
584
585
586 if (pll_freq / m == parent_freq &&
587 pll_freq % m == 0)
588 return 0;
589
590 frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq);
591 frac_m = m * frac_max;
592 if (frac_m > frac)
593 return frac_max;
594 frac -= frac_m;
595
596 return min((u16)frac, (u16)(frac_max - 1));
597}
598
599static bool meson_hdmi_pll_validate_params(struct meson_vpu_priv *priv,
600 unsigned int m,
601 unsigned int frac)
602{
603 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
604
605 if (m < 53 || m > 123)
606 return false;
607 if (frac >= HDMI_FRAC_MAX_GXBB)
608 return false;
609 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
610 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
611
612 if (m < 106 || m > 247)
613 return false;
614 if (frac >= HDMI_FRAC_MAX_GXL)
615 return false;
616 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
617
618 if (m < 106 || m > 247)
619 return false;
620 if (frac >= HDMI_FRAC_MAX_G12A)
621 return false;
622 }
623
624 return true;
625}
626
627static bool meson_hdmi_pll_find_params(struct meson_vpu_priv *priv,
628 unsigned int freq,
629 unsigned int *m,
630 unsigned int *frac,
631 unsigned int *od)
632{
633
634 for (*od = 16 ; *od > 1 ; *od >>= 1) {
635 *m = meson_hdmi_pll_get_m(priv, freq * *od);
636 if (!*m)
637 continue;
638 *frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od);
639
640 debug("PLL params for %dkHz: m=%x frac=%x od=%d\n",
641 freq, *m, *frac, *od);
642
643 if (meson_hdmi_pll_validate_params(priv, *m, *frac))
644 return true;
645 }
646
647 return false;
648}
649
650
651bool meson_vclk_dmt_supported_freq(struct meson_vpu_priv *priv,
652 unsigned int freq)
653{
654 unsigned int od, m, frac;
655
656
657 freq *= 10;
658
659 if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od))
660 return true;
661
662 return false;
663}
664
665
666static void meson_hdmi_pll_generic_set(struct meson_vpu_priv *priv,
667 unsigned int pll_freq)
668{
669 unsigned int od, m, frac, od1, od2, od3;
670
671 if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) {
672 od3 = 1;
673 if (od < 4) {
674 od1 = 2;
675 od2 = 1;
676 } else {
677 od2 = od / 4;
678 od1 = od / od2;
679 }
680
681 debug("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n",
682 pll_freq, m, frac, od1, od2, od3);
683
684 meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
685
686 return;
687 }
688
689 printf("Fatal, unable to find parameters for PLL freq %d\n",
690 pll_freq);
691}
692
693static void
694meson_vclk_set(struct meson_vpu_priv *priv, unsigned int pll_base_freq,
695 unsigned int od1, unsigned int od2, unsigned int od3,
696 unsigned int vid_pll_div, unsigned int vclk_div,
697 unsigned int hdmi_tx_div, unsigned int venc_div,
698 bool hdmi_use_enci, bool vic_alternate_clock)
699{
700 unsigned int m = 0, frac = 0;
701
702
703 hhi_update_bits(HHI_HDMI_CLK_CNTL,
704 CTS_HDMI_SYS_SEL_MASK, 0);
705 hhi_update_bits(HHI_HDMI_CLK_CNTL,
706 CTS_HDMI_SYS_DIV_MASK, 0);
707 hhi_update_bits(HHI_HDMI_CLK_CNTL,
708 CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
709
710
711 if (!od1 && !od2 && !od3) {
712 meson_hdmi_pll_generic_set(priv, pll_base_freq);
713 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
714 switch (pll_base_freq) {
715 case 2970000:
716 m = 0x3d;
717 frac = vic_alternate_clock ? 0xd02 : 0xe00;
718 break;
719 case 4320000:
720 m = vic_alternate_clock ? 0x59 : 0x5a;
721 frac = vic_alternate_clock ? 0xe8f : 0;
722 break;
723 case 5940000:
724 m = 0x7b;
725 frac = vic_alternate_clock ? 0xa05 : 0xc00;
726 break;
727 }
728
729 meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
730 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
731 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
732 switch (pll_base_freq) {
733 case 2970000:
734 m = 0x7b;
735 frac = vic_alternate_clock ? 0x281 : 0x300;
736 break;
737 case 4320000:
738 m = vic_alternate_clock ? 0xb3 : 0xb4;
739 frac = vic_alternate_clock ? 0x347 : 0;
740 break;
741 case 5940000:
742 m = 0xf7;
743 frac = vic_alternate_clock ? 0x102 : 0x200;
744 break;
745 }
746
747 meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
748 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
749 switch (pll_base_freq) {
750 case 2970000:
751 m = 0x7b;
752 frac = vic_alternate_clock ? 0x140b4 : 0x18000;
753 break;
754 case 4320000:
755 m = vic_alternate_clock ? 0xb3 : 0xb4;
756 frac = vic_alternate_clock ? 0x1a3ee : 0;
757 break;
758 case 5940000:
759 m = 0xf7;
760 frac = vic_alternate_clock ? 0x8148 : 0x10000;
761 break;
762 }
763
764 meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
765 }
766
767
768 meson_vid_pll_set(priv, vid_pll_div);
769
770
771 hhi_update_bits(HHI_VID_CLK_CNTL,
772 VCLK_SEL_MASK, 0);
773 hhi_update_bits(HHI_VID_CLK_DIV,
774 VCLK_DIV_MASK, vclk_div - 1);
775
776
777 switch (hdmi_tx_div) {
778 case 1:
779
780 hhi_update_bits(HHI_VID_CLK_CNTL,
781 VCLK_DIV1_EN, VCLK_DIV1_EN);
782
783
784 hhi_update_bits(HHI_HDMI_CLK_CNTL,
785 HDMI_TX_PIXEL_SEL_MASK, 0);
786 break;
787 case 2:
788
789 hhi_update_bits(HHI_VID_CLK_CNTL,
790 VCLK_DIV2_EN, VCLK_DIV2_EN);
791
792
793 hhi_update_bits(HHI_HDMI_CLK_CNTL,
794 HDMI_TX_PIXEL_SEL_MASK,
795 1 << HDMI_TX_PIXEL_SEL_SHIFT);
796 break;
797 case 4:
798
799 hhi_update_bits(HHI_VID_CLK_CNTL,
800 VCLK_DIV4_EN, VCLK_DIV4_EN);
801
802
803 hhi_update_bits(HHI_HDMI_CLK_CNTL,
804 HDMI_TX_PIXEL_SEL_MASK,
805 2 << HDMI_TX_PIXEL_SEL_SHIFT);
806 break;
807 case 6:
808
809 hhi_update_bits(HHI_VID_CLK_CNTL,
810 VCLK_DIV6_EN, VCLK_DIV6_EN);
811
812
813 hhi_update_bits(HHI_HDMI_CLK_CNTL,
814 HDMI_TX_PIXEL_SEL_MASK,
815 3 << HDMI_TX_PIXEL_SEL_SHIFT);
816 break;
817 case 12:
818
819 hhi_update_bits(HHI_VID_CLK_CNTL,
820 VCLK_DIV12_EN, VCLK_DIV12_EN);
821
822
823 hhi_update_bits(HHI_HDMI_CLK_CNTL,
824 HDMI_TX_PIXEL_SEL_MASK,
825 4 << HDMI_TX_PIXEL_SEL_SHIFT);
826 break;
827 }
828 hhi_update_bits(HHI_VID_CLK_CNTL2,
829 HDMI_TX_PIXEL_EN, HDMI_TX_PIXEL_EN);
830
831
832 switch (venc_div) {
833 case 1:
834
835 hhi_update_bits(HHI_VID_CLK_CNTL,
836 VCLK_DIV1_EN, VCLK_DIV1_EN);
837
838 if (hdmi_use_enci)
839
840 hhi_update_bits(HHI_VID_CLK_DIV,
841 CTS_ENCI_SEL_MASK, 0);
842 else
843
844 hhi_update_bits(HHI_VID_CLK_DIV,
845 CTS_ENCP_SEL_MASK, 0);
846 break;
847 case 2:
848
849 hhi_update_bits(HHI_VID_CLK_CNTL,
850 VCLK_DIV2_EN, VCLK_DIV2_EN);
851
852 if (hdmi_use_enci)
853
854 hhi_update_bits(HHI_VID_CLK_DIV,
855 CTS_ENCI_SEL_MASK,
856 1 << CTS_ENCI_SEL_SHIFT);
857 else
858
859 hhi_update_bits(HHI_VID_CLK_DIV,
860 CTS_ENCP_SEL_MASK,
861 1 << CTS_ENCP_SEL_SHIFT);
862 break;
863 case 4:
864
865 hhi_update_bits(HHI_VID_CLK_CNTL,
866 VCLK_DIV4_EN, VCLK_DIV4_EN);
867
868 if (hdmi_use_enci)
869
870 hhi_update_bits(HHI_VID_CLK_DIV,
871 CTS_ENCI_SEL_MASK,
872 2 << CTS_ENCI_SEL_SHIFT);
873 else
874
875 hhi_update_bits(HHI_VID_CLK_DIV,
876 CTS_ENCP_SEL_MASK,
877 2 << CTS_ENCP_SEL_SHIFT);
878 break;
879 case 6:
880
881 hhi_update_bits(HHI_VID_CLK_CNTL,
882 VCLK_DIV6_EN, VCLK_DIV6_EN);
883
884 if (hdmi_use_enci)
885
886 hhi_update_bits(HHI_VID_CLK_DIV,
887 CTS_ENCI_SEL_MASK,
888 3 << CTS_ENCI_SEL_SHIFT);
889 else
890
891 hhi_update_bits(HHI_VID_CLK_DIV,
892 CTS_ENCP_SEL_MASK,
893 3 << CTS_ENCP_SEL_SHIFT);
894 break;
895 case 12:
896
897 hhi_update_bits(HHI_VID_CLK_CNTL,
898 VCLK_DIV12_EN, VCLK_DIV12_EN);
899
900 if (hdmi_use_enci)
901
902 hhi_update_bits(HHI_VID_CLK_DIV,
903 CTS_ENCI_SEL_MASK,
904 4 << CTS_ENCI_SEL_SHIFT);
905 else
906
907 hhi_update_bits(HHI_VID_CLK_DIV,
908 CTS_ENCP_SEL_MASK,
909 4 << CTS_ENCP_SEL_SHIFT);
910 break;
911 }
912
913 if (hdmi_use_enci)
914
915 hhi_update_bits(HHI_VID_CLK_CNTL2,
916 CTS_ENCI_EN, CTS_ENCI_EN);
917 else
918
919 hhi_update_bits(HHI_VID_CLK_CNTL2,
920 CTS_ENCP_EN, CTS_ENCP_EN);
921
922 hhi_update_bits(HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
923}
924
925static void meson_vclk_setup(struct meson_vpu_priv *priv, unsigned int target,
926 unsigned int vclk_freq, unsigned int venc_freq,
927 unsigned int dac_freq, bool hdmi_use_enci)
928{
929 bool vic_alternate_clock = false;
930 unsigned int freq;
931 unsigned int hdmi_tx_div;
932 unsigned int venc_div;
933
934 if (target == MESON_VCLK_TARGET_CVBS) {
935 meson_venci_cvbs_clock_config(priv);
936 return;
937 } else if (target == MESON_VCLK_TARGET_DMT) {
938
939
940
941
942
943
944
945
946 meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0,
947 VID_PLL_DIV_5, 2, 1, 1, false, false);
948 return;
949 }
950
951 hdmi_tx_div = vclk_freq / dac_freq;
952
953 if (hdmi_tx_div == 0) {
954 printf("Fatal Error, invalid HDMI-TX freq %d\n",
955 dac_freq);
956 return;
957 }
958
959 venc_div = vclk_freq / venc_freq;
960
961 if (venc_div == 0) {
962 printf("Fatal Error, invalid HDMI venc freq %d\n",
963 venc_freq);
964 return;
965 }
966
967 for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
968 if (vclk_freq == params[freq].pixel_freq ||
969 vclk_freq == FREQ_1000_1001(params[freq].pixel_freq)) {
970 if (vclk_freq != params[freq].pixel_freq)
971 vic_alternate_clock = true;
972 else
973 vic_alternate_clock = false;
974
975 if (freq == MESON_VCLK_HDMI_ENCI_54000 &&
976 !hdmi_use_enci)
977 continue;
978
979 if (freq == MESON_VCLK_HDMI_DDR_54000 &&
980 hdmi_use_enci)
981 continue;
982
983 if (freq == MESON_VCLK_HDMI_DDR_148500 &&
984 dac_freq == vclk_freq)
985 continue;
986
987 if (freq == MESON_VCLK_HDMI_148500 &&
988 dac_freq != vclk_freq)
989 continue;
990 break;
991 }
992 }
993
994 if (!params[freq].pixel_freq) {
995 pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq);
996 return;
997 }
998
999 meson_vclk_set(priv, params[freq].pll_base_freq,
1000 params[freq].pll_od1, params[freq].pll_od2,
1001 params[freq].pll_od3, params[freq].vid_pll_div,
1002 params[freq].vclk_div, hdmi_tx_div, venc_div,
1003 hdmi_use_enci, vic_alternate_clock);
1004}
1005
1006void meson_vpu_setup_vclk(struct udevice *dev,
1007 const struct display_timing *mode, bool is_cvbs)
1008{
1009 struct meson_vpu_priv *priv = dev_get_priv(dev);
1010 unsigned int vclk_freq;
1011
1012 if (is_cvbs)
1013 return meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS,
1014 0, 0, 0, false);
1015
1016 vclk_freq = mode->pixelclock.typ / 1000;
1017
1018 return meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT,
1019 vclk_freq, vclk_freq, vclk_freq, false);
1020}
1021