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