Loading...
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2016 BayLibre, SAS
4 * Author: Neil Armstrong <narmstrong@baylibre.com>
5 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
6 */
7
8#include <linux/bitfield.h>
9#include <linux/export.h>
10#include <linux/iopoll.h>
11
12#include <drm/drm_modes.h>
13
14#include "meson_drv.h"
15#include "meson_registers.h"
16#include "meson_venc.h"
17#include "meson_vpp.h"
18
19/**
20 * DOC: Video Encoder
21 *
22 * VENC Handle the pixels encoding to the output formats.
23 * We handle the following encodings :
24 *
25 * - CVBS Encoding via the ENCI encoder and VDAC digital to analog converter
26 * - TMDS/HDMI Encoding via ENCI_DIV and ENCP
27 * - Setup of more clock rates for HDMI modes
28 *
29 * What is missing :
30 *
31 * - LCD Panel encoding via ENCL
32 * - TV Panel encoding via ENCT
33 *
34 * VENC paths :
35 *
36 * .. code::
37 *
38 * _____ _____ ____________________
39 * vd1---| |-| | | VENC /---------|----VDAC
40 * vd2---| VIU |-| VPP |-|-----ENCI/-ENCI_DVI-|-|
41 * osd1--| |-| | | \ | X--HDMI-TX
42 * osd2--|_____|-|_____| | |\-ENCP--ENCP_DVI-|-|
43 * | | |
44 * | \--ENCL-----------|----LVDS
45 * |____________________|
46 *
47 * The ENCI is designed for PAl or NTSC encoding and can go through the VDAC
48 * directly for CVBS encoding or through the ENCI_DVI encoder for HDMI.
49 * The ENCP is designed for Progressive encoding but can also generate
50 * 1080i interlaced pixels, and was initially designed to encode pixels for
51 * VDAC to output RGB ou YUV analog outputs.
52 * It's output is only used through the ENCP_DVI encoder for HDMI.
53 * The ENCL LVDS encoder is not implemented.
54 *
55 * The ENCI and ENCP encoders needs specially defined parameters for each
56 * supported mode and thus cannot be determined from standard video timings.
57 *
58 * The ENCI end ENCP DVI encoders are more generic and can generate any timings
59 * from the pixel data generated by ENCI or ENCP, so can use the standard video
60 * timings are source for HW parameters.
61 */
62
63/* HHI Registers */
64#define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */
65#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
66#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbb offset in data sheet */
67#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
68#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbc offset in data sheet */
69#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */
70
71struct meson_cvbs_enci_mode meson_cvbs_enci_pal = {
72 .mode_tag = MESON_VENC_MODE_CVBS_PAL,
73 .hso_begin = 3,
74 .hso_end = 129,
75 .vso_even = 3,
76 .vso_odd = 260,
77 .macv_max_amp = 7,
78 .video_prog_mode = 0xff,
79 .video_mode = 0x13,
80 .sch_adjust = 0x28,
81 .yc_delay = 0x343,
82 .pixel_start = 251,
83 .pixel_end = 1691,
84 .top_field_line_start = 22,
85 .top_field_line_end = 310,
86 .bottom_field_line_start = 23,
87 .bottom_field_line_end = 311,
88 .video_saturation = 9,
89 .video_contrast = 0,
90 .video_brightness = 0,
91 .video_hue = 0,
92 .analog_sync_adj = 0x8080,
93};
94
95struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc = {
96 .mode_tag = MESON_VENC_MODE_CVBS_NTSC,
97 .hso_begin = 5,
98 .hso_end = 129,
99 .vso_even = 3,
100 .vso_odd = 260,
101 .macv_max_amp = 0xb,
102 .video_prog_mode = 0xf0,
103 .video_mode = 0x8,
104 .sch_adjust = 0x20,
105 .yc_delay = 0x333,
106 .pixel_start = 227,
107 .pixel_end = 1667,
108 .top_field_line_start = 18,
109 .top_field_line_end = 258,
110 .bottom_field_line_start = 19,
111 .bottom_field_line_end = 259,
112 .video_saturation = 18,
113 .video_contrast = 3,
114 .video_brightness = 0,
115 .video_hue = 0,
116 .analog_sync_adj = 0x9c00,
117};
118
119union meson_hdmi_venc_mode {
120 struct {
121 unsigned int mode_tag;
122 unsigned int hso_begin;
123 unsigned int hso_end;
124 unsigned int vso_even;
125 unsigned int vso_odd;
126 unsigned int macv_max_amp;
127 unsigned int video_prog_mode;
128 unsigned int video_mode;
129 unsigned int sch_adjust;
130 unsigned int yc_delay;
131 unsigned int pixel_start;
132 unsigned int pixel_end;
133 unsigned int top_field_line_start;
134 unsigned int top_field_line_end;
135 unsigned int bottom_field_line_start;
136 unsigned int bottom_field_line_end;
137 } enci;
138 struct {
139 unsigned int dvi_settings;
140 unsigned int video_mode;
141 unsigned int video_mode_adv;
142 unsigned int video_prog_mode;
143 bool video_prog_mode_present;
144 unsigned int video_sync_mode;
145 bool video_sync_mode_present;
146 unsigned int video_yc_dly;
147 bool video_yc_dly_present;
148 unsigned int video_rgb_ctrl;
149 bool video_rgb_ctrl_present;
150 unsigned int video_filt_ctrl;
151 bool video_filt_ctrl_present;
152 unsigned int video_ofld_voav_ofst;
153 bool video_ofld_voav_ofst_present;
154 unsigned int yfp1_htime;
155 unsigned int yfp2_htime;
156 unsigned int max_pxcnt;
157 unsigned int hspuls_begin;
158 unsigned int hspuls_end;
159 unsigned int hspuls_switch;
160 unsigned int vspuls_begin;
161 unsigned int vspuls_end;
162 unsigned int vspuls_bline;
163 unsigned int vspuls_eline;
164 unsigned int eqpuls_begin;
165 bool eqpuls_begin_present;
166 unsigned int eqpuls_end;
167 bool eqpuls_end_present;
168 unsigned int eqpuls_bline;
169 bool eqpuls_bline_present;
170 unsigned int eqpuls_eline;
171 bool eqpuls_eline_present;
172 unsigned int havon_begin;
173 unsigned int havon_end;
174 unsigned int vavon_bline;
175 unsigned int vavon_eline;
176 unsigned int hso_begin;
177 unsigned int hso_end;
178 unsigned int vso_begin;
179 unsigned int vso_end;
180 unsigned int vso_bline;
181 unsigned int vso_eline;
182 bool vso_eline_present;
183 unsigned int sy_val;
184 bool sy_val_present;
185 unsigned int sy2_val;
186 bool sy2_val_present;
187 unsigned int max_lncnt;
188 } encp;
189};
190
191static union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = {
192 .enci = {
193 .hso_begin = 5,
194 .hso_end = 129,
195 .vso_even = 3,
196 .vso_odd = 260,
197 .macv_max_amp = 0xb,
198 .video_prog_mode = 0xf0,
199 .video_mode = 0x8,
200 .sch_adjust = 0x20,
201 .yc_delay = 0,
202 .pixel_start = 227,
203 .pixel_end = 1667,
204 .top_field_line_start = 18,
205 .top_field_line_end = 258,
206 .bottom_field_line_start = 19,
207 .bottom_field_line_end = 259,
208 },
209};
210
211static union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = {
212 .enci = {
213 .hso_begin = 3,
214 .hso_end = 129,
215 .vso_even = 3,
216 .vso_odd = 260,
217 .macv_max_amp = 0x7,
218 .video_prog_mode = 0xff,
219 .video_mode = 0x13,
220 .sch_adjust = 0x28,
221 .yc_delay = 0x333,
222 .pixel_start = 251,
223 .pixel_end = 1691,
224 .top_field_line_start = 22,
225 .top_field_line_end = 310,
226 .bottom_field_line_start = 23,
227 .bottom_field_line_end = 311,
228 },
229};
230
231static union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p = {
232 .encp = {
233 .dvi_settings = 0x21,
234 .video_mode = 0x4000,
235 .video_mode_adv = 0x9,
236 .video_prog_mode = 0,
237 .video_prog_mode_present = true,
238 .video_sync_mode = 7,
239 .video_sync_mode_present = true,
240 /* video_yc_dly */
241 /* video_rgb_ctrl */
242 .video_filt_ctrl = 0x2052,
243 .video_filt_ctrl_present = true,
244 /* video_ofld_voav_ofst */
245 .yfp1_htime = 244,
246 .yfp2_htime = 1630,
247 .max_pxcnt = 1715,
248 .hspuls_begin = 0x22,
249 .hspuls_end = 0xa0,
250 .hspuls_switch = 88,
251 .vspuls_begin = 0,
252 .vspuls_end = 1589,
253 .vspuls_bline = 0,
254 .vspuls_eline = 5,
255 .havon_begin = 249,
256 .havon_end = 1689,
257 .vavon_bline = 42,
258 .vavon_eline = 521,
259 /* eqpuls_begin */
260 /* eqpuls_end */
261 /* eqpuls_bline */
262 /* eqpuls_eline */
263 .hso_begin = 3,
264 .hso_end = 5,
265 .vso_begin = 3,
266 .vso_end = 5,
267 .vso_bline = 0,
268 /* vso_eline */
269 .sy_val = 8,
270 .sy_val_present = true,
271 .sy2_val = 0x1d8,
272 .sy2_val_present = true,
273 .max_lncnt = 524,
274 },
275};
276
277static union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p = {
278 .encp = {
279 .dvi_settings = 0x21,
280 .video_mode = 0x4000,
281 .video_mode_adv = 0x9,
282 .video_prog_mode = 0,
283 .video_prog_mode_present = true,
284 .video_sync_mode = 7,
285 .video_sync_mode_present = true,
286 /* video_yc_dly */
287 /* video_rgb_ctrl */
288 .video_filt_ctrl = 0x52,
289 .video_filt_ctrl_present = true,
290 /* video_ofld_voav_ofst */
291 .yfp1_htime = 235,
292 .yfp2_htime = 1674,
293 .max_pxcnt = 1727,
294 .hspuls_begin = 0,
295 .hspuls_end = 0x80,
296 .hspuls_switch = 88,
297 .vspuls_begin = 0,
298 .vspuls_end = 1599,
299 .vspuls_bline = 0,
300 .vspuls_eline = 4,
301 .havon_begin = 235,
302 .havon_end = 1674,
303 .vavon_bline = 44,
304 .vavon_eline = 619,
305 /* eqpuls_begin */
306 /* eqpuls_end */
307 /* eqpuls_bline */
308 /* eqpuls_eline */
309 .hso_begin = 0x80,
310 .hso_end = 0,
311 .vso_begin = 0,
312 .vso_end = 5,
313 .vso_bline = 0,
314 /* vso_eline */
315 .sy_val = 8,
316 .sy_val_present = true,
317 .sy2_val = 0x1d8,
318 .sy2_val_present = true,
319 .max_lncnt = 624,
320 },
321};
322
323static union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60 = {
324 .encp = {
325 .dvi_settings = 0x2029,
326 .video_mode = 0x4040,
327 .video_mode_adv = 0x19,
328 /* video_prog_mode */
329 /* video_sync_mode */
330 /* video_yc_dly */
331 /* video_rgb_ctrl */
332 /* video_filt_ctrl */
333 /* video_ofld_voav_ofst */
334 .yfp1_htime = 648,
335 .yfp2_htime = 3207,
336 .max_pxcnt = 3299,
337 .hspuls_begin = 80,
338 .hspuls_end = 240,
339 .hspuls_switch = 80,
340 .vspuls_begin = 688,
341 .vspuls_end = 3248,
342 .vspuls_bline = 4,
343 .vspuls_eline = 8,
344 .havon_begin = 648,
345 .havon_end = 3207,
346 .vavon_bline = 29,
347 .vavon_eline = 748,
348 /* eqpuls_begin */
349 /* eqpuls_end */
350 /* eqpuls_bline */
351 /* eqpuls_eline */
352 .hso_begin = 256,
353 .hso_end = 168,
354 .vso_begin = 168,
355 .vso_end = 256,
356 .vso_bline = 0,
357 .vso_eline = 5,
358 .vso_eline_present = true,
359 /* sy_val */
360 /* sy2_val */
361 .max_lncnt = 749,
362 },
363};
364
365static union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50 = {
366 .encp = {
367 .dvi_settings = 0x202d,
368 .video_mode = 0x4040,
369 .video_mode_adv = 0x19,
370 .video_prog_mode = 0x100,
371 .video_prog_mode_present = true,
372 .video_sync_mode = 0x407,
373 .video_sync_mode_present = true,
374 .video_yc_dly = 0,
375 .video_yc_dly_present = true,
376 /* video_rgb_ctrl */
377 /* video_filt_ctrl */
378 /* video_ofld_voav_ofst */
379 .yfp1_htime = 648,
380 .yfp2_htime = 3207,
381 .max_pxcnt = 3959,
382 .hspuls_begin = 80,
383 .hspuls_end = 240,
384 .hspuls_switch = 80,
385 .vspuls_begin = 688,
386 .vspuls_end = 3248,
387 .vspuls_bline = 4,
388 .vspuls_eline = 8,
389 .havon_begin = 648,
390 .havon_end = 3207,
391 .vavon_bline = 29,
392 .vavon_eline = 748,
393 /* eqpuls_begin */
394 /* eqpuls_end */
395 /* eqpuls_bline */
396 /* eqpuls_eline */
397 .hso_begin = 128,
398 .hso_end = 208,
399 .vso_begin = 128,
400 .vso_end = 128,
401 .vso_bline = 0,
402 .vso_eline = 5,
403 .vso_eline_present = true,
404 /* sy_val */
405 /* sy2_val */
406 .max_lncnt = 749,
407 },
408};
409
410static union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60 = {
411 .encp = {
412 .dvi_settings = 0x2029,
413 .video_mode = 0x5ffc,
414 .video_mode_adv = 0x19,
415 .video_prog_mode = 0x100,
416 .video_prog_mode_present = true,
417 .video_sync_mode = 0x207,
418 .video_sync_mode_present = true,
419 /* video_yc_dly */
420 /* video_rgb_ctrl */
421 /* video_filt_ctrl */
422 .video_ofld_voav_ofst = 0x11,
423 .video_ofld_voav_ofst_present = true,
424 .yfp1_htime = 516,
425 .yfp2_htime = 4355,
426 .max_pxcnt = 4399,
427 .hspuls_begin = 88,
428 .hspuls_end = 264,
429 .hspuls_switch = 88,
430 .vspuls_begin = 440,
431 .vspuls_end = 2200,
432 .vspuls_bline = 0,
433 .vspuls_eline = 4,
434 .havon_begin = 516,
435 .havon_end = 4355,
436 .vavon_bline = 20,
437 .vavon_eline = 559,
438 .eqpuls_begin = 2288,
439 .eqpuls_begin_present = true,
440 .eqpuls_end = 2464,
441 .eqpuls_end_present = true,
442 .eqpuls_bline = 0,
443 .eqpuls_bline_present = true,
444 .eqpuls_eline = 4,
445 .eqpuls_eline_present = true,
446 .hso_begin = 264,
447 .hso_end = 176,
448 .vso_begin = 88,
449 .vso_end = 88,
450 .vso_bline = 0,
451 .vso_eline = 5,
452 .vso_eline_present = true,
453 /* sy_val */
454 /* sy2_val */
455 .max_lncnt = 1124,
456 },
457};
458
459static union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50 = {
460 .encp = {
461 .dvi_settings = 0x202d,
462 .video_mode = 0x5ffc,
463 .video_mode_adv = 0x19,
464 .video_prog_mode = 0x100,
465 .video_prog_mode_present = true,
466 .video_sync_mode = 0x7,
467 .video_sync_mode_present = true,
468 /* video_yc_dly */
469 /* video_rgb_ctrl */
470 /* video_filt_ctrl */
471 .video_ofld_voav_ofst = 0x11,
472 .video_ofld_voav_ofst_present = true,
473 .yfp1_htime = 526,
474 .yfp2_htime = 4365,
475 .max_pxcnt = 5279,
476 .hspuls_begin = 88,
477 .hspuls_end = 264,
478 .hspuls_switch = 88,
479 .vspuls_begin = 440,
480 .vspuls_end = 2200,
481 .vspuls_bline = 0,
482 .vspuls_eline = 4,
483 .havon_begin = 526,
484 .havon_end = 4365,
485 .vavon_bline = 20,
486 .vavon_eline = 559,
487 .eqpuls_begin = 2288,
488 .eqpuls_begin_present = true,
489 .eqpuls_end = 2464,
490 .eqpuls_end_present = true,
491 .eqpuls_bline = 0,
492 .eqpuls_bline_present = true,
493 .eqpuls_eline = 4,
494 .eqpuls_eline_present = true,
495 .hso_begin = 142,
496 .hso_end = 230,
497 .vso_begin = 142,
498 .vso_end = 142,
499 .vso_bline = 0,
500 .vso_eline = 5,
501 .vso_eline_present = true,
502 /* sy_val */
503 /* sy2_val */
504 .max_lncnt = 1124,
505 },
506};
507
508static union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24 = {
509 .encp = {
510 .dvi_settings = 0xd,
511 .video_mode = 0x4040,
512 .video_mode_adv = 0x18,
513 .video_prog_mode = 0x100,
514 .video_prog_mode_present = true,
515 .video_sync_mode = 0x7,
516 .video_sync_mode_present = true,
517 .video_yc_dly = 0,
518 .video_yc_dly_present = true,
519 .video_rgb_ctrl = 2,
520 .video_rgb_ctrl_present = true,
521 .video_filt_ctrl = 0x1052,
522 .video_filt_ctrl_present = true,
523 /* video_ofld_voav_ofst */
524 .yfp1_htime = 271,
525 .yfp2_htime = 2190,
526 .max_pxcnt = 2749,
527 .hspuls_begin = 44,
528 .hspuls_end = 132,
529 .hspuls_switch = 44,
530 .vspuls_begin = 220,
531 .vspuls_end = 2140,
532 .vspuls_bline = 0,
533 .vspuls_eline = 4,
534 .havon_begin = 271,
535 .havon_end = 2190,
536 .vavon_bline = 41,
537 .vavon_eline = 1120,
538 /* eqpuls_begin */
539 /* eqpuls_end */
540 .eqpuls_bline = 0,
541 .eqpuls_bline_present = true,
542 .eqpuls_eline = 4,
543 .eqpuls_eline_present = true,
544 .hso_begin = 79,
545 .hso_end = 123,
546 .vso_begin = 79,
547 .vso_end = 79,
548 .vso_bline = 0,
549 .vso_eline = 5,
550 .vso_eline_present = true,
551 /* sy_val */
552 /* sy2_val */
553 .max_lncnt = 1124,
554 },
555};
556
557static union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30 = {
558 .encp = {
559 .dvi_settings = 0x1,
560 .video_mode = 0x4040,
561 .video_mode_adv = 0x18,
562 .video_prog_mode = 0x100,
563 .video_prog_mode_present = true,
564 /* video_sync_mode */
565 /* video_yc_dly */
566 /* video_rgb_ctrl */
567 .video_filt_ctrl = 0x1052,
568 .video_filt_ctrl_present = true,
569 /* video_ofld_voav_ofst */
570 .yfp1_htime = 140,
571 .yfp2_htime = 2060,
572 .max_pxcnt = 2199,
573 .hspuls_begin = 2156,
574 .hspuls_end = 44,
575 .hspuls_switch = 44,
576 .vspuls_begin = 140,
577 .vspuls_end = 2059,
578 .vspuls_bline = 0,
579 .vspuls_eline = 4,
580 .havon_begin = 148,
581 .havon_end = 2067,
582 .vavon_bline = 41,
583 .vavon_eline = 1120,
584 /* eqpuls_begin */
585 /* eqpuls_end */
586 /* eqpuls_bline */
587 /* eqpuls_eline */
588 .hso_begin = 44,
589 .hso_end = 2156,
590 .vso_begin = 2100,
591 .vso_end = 2164,
592 .vso_bline = 0,
593 .vso_eline = 5,
594 .vso_eline_present = true,
595 /* sy_val */
596 /* sy2_val */
597 .max_lncnt = 1124,
598 },
599};
600
601static union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50 = {
602 .encp = {
603 .dvi_settings = 0xd,
604 .video_mode = 0x4040,
605 .video_mode_adv = 0x18,
606 .video_prog_mode = 0x100,
607 .video_prog_mode_present = true,
608 .video_sync_mode = 0x7,
609 .video_sync_mode_present = true,
610 .video_yc_dly = 0,
611 .video_yc_dly_present = true,
612 .video_rgb_ctrl = 2,
613 .video_rgb_ctrl_present = true,
614 /* video_filt_ctrl */
615 /* video_ofld_voav_ofst */
616 .yfp1_htime = 271,
617 .yfp2_htime = 2190,
618 .max_pxcnt = 2639,
619 .hspuls_begin = 44,
620 .hspuls_end = 132,
621 .hspuls_switch = 44,
622 .vspuls_begin = 220,
623 .vspuls_end = 2140,
624 .vspuls_bline = 0,
625 .vspuls_eline = 4,
626 .havon_begin = 271,
627 .havon_end = 2190,
628 .vavon_bline = 41,
629 .vavon_eline = 1120,
630 /* eqpuls_begin */
631 /* eqpuls_end */
632 .eqpuls_bline = 0,
633 .eqpuls_bline_present = true,
634 .eqpuls_eline = 4,
635 .eqpuls_eline_present = true,
636 .hso_begin = 79,
637 .hso_end = 123,
638 .vso_begin = 79,
639 .vso_end = 79,
640 .vso_bline = 0,
641 .vso_eline = 5,
642 .vso_eline_present = true,
643 /* sy_val */
644 /* sy2_val */
645 .max_lncnt = 1124,
646 },
647};
648
649static union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
650 .encp = {
651 .dvi_settings = 0x1,
652 .video_mode = 0x4040,
653 .video_mode_adv = 0x18,
654 .video_prog_mode = 0x100,
655 .video_prog_mode_present = true,
656 /* video_sync_mode */
657 /* video_yc_dly */
658 /* video_rgb_ctrl */
659 .video_filt_ctrl = 0x1052,
660 .video_filt_ctrl_present = true,
661 /* video_ofld_voav_ofst */
662 .yfp1_htime = 140,
663 .yfp2_htime = 2060,
664 .max_pxcnt = 2199,
665 .hspuls_begin = 2156,
666 .hspuls_end = 44,
667 .hspuls_switch = 44,
668 .vspuls_begin = 140,
669 .vspuls_end = 2059,
670 .vspuls_bline = 0,
671 .vspuls_eline = 4,
672 .havon_begin = 148,
673 .havon_end = 2067,
674 .vavon_bline = 41,
675 .vavon_eline = 1120,
676 /* eqpuls_begin */
677 /* eqpuls_end */
678 /* eqpuls_bline */
679 /* eqpuls_eline */
680 .hso_begin = 44,
681 .hso_end = 2156,
682 .vso_begin = 2100,
683 .vso_end = 2164,
684 .vso_bline = 0,
685 .vso_eline = 5,
686 .vso_eline_present = true,
687 /* sy_val */
688 /* sy2_val */
689 .max_lncnt = 1124,
690 },
691};
692
693static union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p24 = {
694 .encp = {
695 .dvi_settings = 0x1,
696 .video_mode = 0x4040,
697 .video_mode_adv = 0x8,
698 /* video_sync_mode */
699 /* video_yc_dly */
700 /* video_rgb_ctrl */
701 .video_filt_ctrl = 0x1000,
702 .video_filt_ctrl_present = true,
703 /* video_ofld_voav_ofst */
704 .yfp1_htime = 140,
705 .yfp2_htime = 140+3840,
706 .max_pxcnt = 3840+1660-1,
707 .hspuls_begin = 2156+1920,
708 .hspuls_end = 44,
709 .hspuls_switch = 44,
710 .vspuls_begin = 140,
711 .vspuls_end = 2059+1920,
712 .vspuls_bline = 0,
713 .vspuls_eline = 4,
714 .havon_begin = 148,
715 .havon_end = 3987,
716 .vavon_bline = 89,
717 .vavon_eline = 2248,
718 /* eqpuls_begin */
719 /* eqpuls_end */
720 /* eqpuls_bline */
721 /* eqpuls_eline */
722 .hso_begin = 44,
723 .hso_end = 2156+1920,
724 .vso_begin = 2100+1920,
725 .vso_end = 2164+1920,
726 .vso_bline = 51,
727 .vso_eline = 53,
728 .vso_eline_present = true,
729 /* sy_val */
730 /* sy2_val */
731 .max_lncnt = 2249,
732 },
733};
734
735static union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p25 = {
736 .encp = {
737 .dvi_settings = 0x1,
738 .video_mode = 0x4040,
739 .video_mode_adv = 0x8,
740 /* video_sync_mode */
741 /* video_yc_dly */
742 /* video_rgb_ctrl */
743 .video_filt_ctrl = 0x1000,
744 .video_filt_ctrl_present = true,
745 /* video_ofld_voav_ofst */
746 .yfp1_htime = 140,
747 .yfp2_htime = 140+3840,
748 .max_pxcnt = 3840+1440-1,
749 .hspuls_begin = 2156+1920,
750 .hspuls_end = 44,
751 .hspuls_switch = 44,
752 .vspuls_begin = 140,
753 .vspuls_end = 2059+1920,
754 .vspuls_bline = 0,
755 .vspuls_eline = 4,
756 .havon_begin = 148,
757 .havon_end = 3987,
758 .vavon_bline = 89,
759 .vavon_eline = 2248,
760 /* eqpuls_begin */
761 /* eqpuls_end */
762 /* eqpuls_bline */
763 /* eqpuls_eline */
764 .hso_begin = 44,
765 .hso_end = 2156+1920,
766 .vso_begin = 2100+1920,
767 .vso_end = 2164+1920,
768 .vso_bline = 51,
769 .vso_eline = 53,
770 .vso_eline_present = true,
771 /* sy_val */
772 /* sy2_val */
773 .max_lncnt = 2249,
774 },
775};
776
777static union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p30 = {
778 .encp = {
779 .dvi_settings = 0x1,
780 .video_mode = 0x4040,
781 .video_mode_adv = 0x8,
782 /* video_sync_mode */
783 /* video_yc_dly */
784 /* video_rgb_ctrl */
785 .video_filt_ctrl = 0x1000,
786 .video_filt_ctrl_present = true,
787 /* video_ofld_voav_ofst */
788 .yfp1_htime = 140,
789 .yfp2_htime = 140+3840,
790 .max_pxcnt = 3840+560-1,
791 .hspuls_begin = 2156+1920,
792 .hspuls_end = 44,
793 .hspuls_switch = 44,
794 .vspuls_begin = 140,
795 .vspuls_end = 2059+1920,
796 .vspuls_bline = 0,
797 .vspuls_eline = 4,
798 .havon_begin = 148,
799 .havon_end = 3987,
800 .vavon_bline = 89,
801 .vavon_eline = 2248,
802 /* eqpuls_begin */
803 /* eqpuls_end */
804 /* eqpuls_bline */
805 /* eqpuls_eline */
806 .hso_begin = 44,
807 .hso_end = 2156+1920,
808 .vso_begin = 2100+1920,
809 .vso_end = 2164+1920,
810 .vso_bline = 51,
811 .vso_eline = 53,
812 .vso_eline_present = true,
813 /* sy_val */
814 /* sy2_val */
815 .max_lncnt = 2249,
816 },
817};
818
819static struct meson_hdmi_venc_vic_mode {
820 unsigned int vic;
821 union meson_hdmi_venc_mode *mode;
822} meson_hdmi_venc_vic_modes[] = {
823 { 6, &meson_hdmi_enci_mode_480i },
824 { 7, &meson_hdmi_enci_mode_480i },
825 { 21, &meson_hdmi_enci_mode_576i },
826 { 22, &meson_hdmi_enci_mode_576i },
827 { 2, &meson_hdmi_encp_mode_480p },
828 { 3, &meson_hdmi_encp_mode_480p },
829 { 17, &meson_hdmi_encp_mode_576p },
830 { 18, &meson_hdmi_encp_mode_576p },
831 { 4, &meson_hdmi_encp_mode_720p60 },
832 { 19, &meson_hdmi_encp_mode_720p50 },
833 { 5, &meson_hdmi_encp_mode_1080i60 },
834 { 20, &meson_hdmi_encp_mode_1080i50 },
835 { 32, &meson_hdmi_encp_mode_1080p24 },
836 { 33, &meson_hdmi_encp_mode_1080p50 },
837 { 34, &meson_hdmi_encp_mode_1080p30 },
838 { 31, &meson_hdmi_encp_mode_1080p50 },
839 { 16, &meson_hdmi_encp_mode_1080p60 },
840 { 93, &meson_hdmi_encp_mode_2160p24 },
841 { 94, &meson_hdmi_encp_mode_2160p25 },
842 { 95, &meson_hdmi_encp_mode_2160p30 },
843 { 96, &meson_hdmi_encp_mode_2160p25 },
844 { 97, &meson_hdmi_encp_mode_2160p30 },
845 { 0, NULL}, /* sentinel */
846};
847
848static signed int to_signed(unsigned int a)
849{
850 if (a <= 7)
851 return a;
852 else
853 return a - 16;
854}
855
856static unsigned long modulo(unsigned long a, unsigned long b)
857{
858 if (a >= b)
859 return a - b;
860 else
861 return a;
862}
863
864enum drm_mode_status
865meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode)
866{
867 if (mode->flags & ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
868 DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC))
869 return MODE_BAD;
870
871 if (mode->hdisplay < 400 || mode->hdisplay > 1920)
872 return MODE_BAD_HVALUE;
873
874 if (mode->vdisplay < 480 || mode->vdisplay > 1920)
875 return MODE_BAD_VVALUE;
876
877 return MODE_OK;
878}
879EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode);
880
881bool meson_venc_hdmi_supported_vic(int vic)
882{
883 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
884
885 while (vmode->vic && vmode->mode) {
886 if (vmode->vic == vic)
887 return true;
888 vmode++;
889 }
890
891 return false;
892}
893EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic);
894
895static void meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode,
896 union meson_hdmi_venc_mode *dmt_mode)
897{
898 memset(dmt_mode, 0, sizeof(*dmt_mode));
899
900 dmt_mode->encp.dvi_settings = 0x21;
901 dmt_mode->encp.video_mode = 0x4040;
902 dmt_mode->encp.video_mode_adv = 0x18;
903 dmt_mode->encp.max_pxcnt = mode->htotal - 1;
904 dmt_mode->encp.havon_begin = mode->htotal - mode->hsync_start;
905 dmt_mode->encp.havon_end = dmt_mode->encp.havon_begin +
906 mode->hdisplay - 1;
907 dmt_mode->encp.vavon_bline = mode->vtotal - mode->vsync_start;
908 dmt_mode->encp.vavon_eline = dmt_mode->encp.vavon_bline +
909 mode->vdisplay - 1;
910 dmt_mode->encp.hso_begin = 0;
911 dmt_mode->encp.hso_end = mode->hsync_end - mode->hsync_start;
912 dmt_mode->encp.vso_begin = 30;
913 dmt_mode->encp.vso_end = 50;
914 dmt_mode->encp.vso_bline = 0;
915 dmt_mode->encp.vso_eline = mode->vsync_end - mode->vsync_start;
916 dmt_mode->encp.vso_eline_present = true;
917 dmt_mode->encp.max_lncnt = mode->vtotal - 1;
918}
919
920static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic)
921{
922 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
923
924 while (vmode->vic && vmode->mode) {
925 if (vmode->vic == vic)
926 return vmode->mode;
927 vmode++;
928 }
929
930 return NULL;
931}
932
933bool meson_venc_hdmi_venc_repeat(int vic)
934{
935 /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
936 if (vic == 6 || vic == 7 || /* 480i */
937 vic == 21 || vic == 22 || /* 576i */
938 vic == 17 || vic == 18 || /* 576p */
939 vic == 2 || vic == 3 || /* 480p */
940 vic == 4 || /* 720p60 */
941 vic == 19 || /* 720p50 */
942 vic == 5 || /* 1080i60 */
943 vic == 20) /* 1080i50 */
944 return true;
945
946 return false;
947}
948EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat);
949
950void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
951 unsigned int ycrcb_map,
952 bool yuv420_mode,
953 const struct drm_display_mode *mode)
954{
955 union meson_hdmi_venc_mode *vmode = NULL;
956 union meson_hdmi_venc_mode vmode_dmt;
957 bool use_enci = false;
958 bool venc_repeat = false;
959 bool hdmi_repeat = false;
960 unsigned int venc_hdmi_latency = 2;
961 unsigned long total_pixels_venc = 0;
962 unsigned long active_pixels_venc = 0;
963 unsigned long front_porch_venc = 0;
964 unsigned long hsync_pixels_venc = 0;
965 unsigned long de_h_begin = 0;
966 unsigned long de_h_end = 0;
967 unsigned long de_v_begin_even = 0;
968 unsigned long de_v_end_even = 0;
969 unsigned long de_v_begin_odd = 0;
970 unsigned long de_v_end_odd = 0;
971 unsigned long hs_begin = 0;
972 unsigned long hs_end = 0;
973 unsigned long vs_adjust = 0;
974 unsigned long vs_bline_evn = 0;
975 unsigned long vs_eline_evn = 0;
976 unsigned long vs_bline_odd = 0;
977 unsigned long vs_eline_odd = 0;
978 unsigned long vso_begin_evn = 0;
979 unsigned long vso_begin_odd = 0;
980 unsigned int eof_lines;
981 unsigned int sof_lines;
982 unsigned int vsync_lines;
983 u32 reg;
984
985 /* Use VENCI for 480i and 576i and double HDMI pixels */
986 if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
987 hdmi_repeat = true;
988 use_enci = true;
989 venc_hdmi_latency = 1;
990 }
991
992 if (meson_venc_hdmi_supported_vic(vic)) {
993 vmode = meson_venc_hdmi_get_vic_vmode(vic);
994 if (!vmode) {
995 dev_err(priv->dev, "%s: Fatal Error, unsupported mode "
996 DRM_MODE_FMT "\n", __func__,
997 DRM_MODE_ARG(mode));
998 return;
999 }
1000 } else {
1001 meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt);
1002 vmode = &vmode_dmt;
1003 use_enci = false;
1004 }
1005
1006 /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
1007 if (meson_venc_hdmi_venc_repeat(vic))
1008 venc_repeat = true;
1009
1010 eof_lines = mode->vsync_start - mode->vdisplay;
1011 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1012 eof_lines /= 2;
1013 sof_lines = mode->vtotal - mode->vsync_end;
1014 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1015 sof_lines /= 2;
1016 vsync_lines = mode->vsync_end - mode->vsync_start;
1017 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1018 vsync_lines /= 2;
1019
1020 total_pixels_venc = mode->htotal;
1021 if (hdmi_repeat)
1022 total_pixels_venc /= 2;
1023 if (venc_repeat)
1024 total_pixels_venc *= 2;
1025
1026 active_pixels_venc = mode->hdisplay;
1027 if (hdmi_repeat)
1028 active_pixels_venc /= 2;
1029 if (venc_repeat)
1030 active_pixels_venc *= 2;
1031
1032 front_porch_venc = (mode->hsync_start - mode->hdisplay);
1033 if (hdmi_repeat)
1034 front_porch_venc /= 2;
1035 if (venc_repeat)
1036 front_porch_venc *= 2;
1037
1038 hsync_pixels_venc = (mode->hsync_end - mode->hsync_start);
1039 if (hdmi_repeat)
1040 hsync_pixels_venc /= 2;
1041 if (venc_repeat)
1042 hsync_pixels_venc *= 2;
1043
1044 /* Disable VDACs */
1045 writel_bits_relaxed(0xff, 0xff,
1046 priv->io_base + _REG(VENC_VDAC_SETTING));
1047
1048 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
1049 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
1050
1051 if (use_enci) {
1052 unsigned int lines_f0;
1053 unsigned int lines_f1;
1054
1055 /* CVBS Filter settings */
1056 writel_relaxed(ENCI_CFILT_CMPT_SEL_HIGH | 0x10,
1057 priv->io_base + _REG(ENCI_CFILT_CTRL));
1058 writel_relaxed(ENCI_CFILT_CMPT_CR_DLY(2) |
1059 ENCI_CFILT_CMPT_CB_DLY(1),
1060 priv->io_base + _REG(ENCI_CFILT_CTRL2));
1061
1062 /* Digital Video Select : Interlace, clk27 clk, external */
1063 writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING));
1064
1065 /* Reset Video Mode */
1066 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE));
1067 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
1068
1069 /* Horizontal sync signal output */
1070 writel_relaxed(vmode->enci.hso_begin,
1071 priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN));
1072 writel_relaxed(vmode->enci.hso_end,
1073 priv->io_base + _REG(ENCI_SYNC_HSO_END));
1074
1075 /* Vertical Sync lines */
1076 writel_relaxed(vmode->enci.vso_even,
1077 priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN));
1078 writel_relaxed(vmode->enci.vso_odd,
1079 priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));
1080
1081 /* Macrovision max amplitude change */
1082 writel_relaxed(ENCI_MACV_MAX_AMP_ENABLE_CHANGE |
1083 ENCI_MACV_MAX_AMP_VAL(vmode->enci.macv_max_amp),
1084 priv->io_base + _REG(ENCI_MACV_MAX_AMP));
1085
1086 /* Video mode */
1087 writel_relaxed(vmode->enci.video_prog_mode,
1088 priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
1089 writel_relaxed(vmode->enci.video_mode,
1090 priv->io_base + _REG(ENCI_VIDEO_MODE));
1091
1092 /*
1093 * Advanced Video Mode :
1094 * Demux shifting 0x2
1095 * Blank line end at line17/22
1096 * High bandwidth Luma Filter
1097 * Low bandwidth Chroma Filter
1098 * Bypass luma low pass filter
1099 * No macrovision on CSYNC
1100 */
1101 writel_relaxed(ENCI_VIDEO_MODE_ADV_DMXMD(2) |
1102 ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 |
1103 ENCI_VIDEO_MODE_ADV_YBW_HIGH,
1104 priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
1105
1106 writel(vmode->enci.sch_adjust,
1107 priv->io_base + _REG(ENCI_VIDEO_SCH));
1108
1109 /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
1110 writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE));
1111
1112 if (vmode->enci.yc_delay)
1113 writel_relaxed(vmode->enci.yc_delay,
1114 priv->io_base + _REG(ENCI_YC_DELAY));
1115
1116
1117 /* UNreset Interlaced TV Encoder */
1118 writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST));
1119
1120 /*
1121 * Enable Vfifo2vd and set Y_Cb_Y_Cr:
1122 * Corresponding value:
1123 * Y => 00 or 10
1124 * Cb => 01
1125 * Cr => 11
1126 * Ex: 0x4e => 01001110 would mean Cb/Y/Cr/Y
1127 */
1128 writel_relaxed(ENCI_VFIFO2VD_CTL_ENABLE |
1129 ENCI_VFIFO2VD_CTL_VD_SEL(0x4e),
1130 priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
1131
1132 /* Timings */
1133 writel_relaxed(vmode->enci.pixel_start,
1134 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START));
1135 writel_relaxed(vmode->enci.pixel_end,
1136 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END));
1137
1138 writel_relaxed(vmode->enci.top_field_line_start,
1139 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START));
1140 writel_relaxed(vmode->enci.top_field_line_end,
1141 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END));
1142
1143 writel_relaxed(vmode->enci.bottom_field_line_start,
1144 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START));
1145 writel_relaxed(vmode->enci.bottom_field_line_end,
1146 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END));
1147
1148 /* Select ENCI for VIU */
1149 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);
1150
1151 /* Interlace video enable */
1152 writel_relaxed(ENCI_VIDEO_EN_ENABLE,
1153 priv->io_base + _REG(ENCI_VIDEO_EN));
1154
1155 lines_f0 = mode->vtotal >> 1;
1156 lines_f1 = lines_f0 + 1;
1157
1158 de_h_begin = modulo(readl_relaxed(priv->io_base +
1159 _REG(ENCI_VFIFO2VD_PIXEL_START))
1160 + venc_hdmi_latency,
1161 total_pixels_venc);
1162 de_h_end = modulo(de_h_begin + active_pixels_venc,
1163 total_pixels_venc);
1164
1165 writel_relaxed(de_h_begin,
1166 priv->io_base + _REG(ENCI_DE_H_BEGIN));
1167 writel_relaxed(de_h_end,
1168 priv->io_base + _REG(ENCI_DE_H_END));
1169
1170 de_v_begin_even = readl_relaxed(priv->io_base +
1171 _REG(ENCI_VFIFO2VD_LINE_TOP_START));
1172 de_v_end_even = de_v_begin_even + mode->vdisplay;
1173 de_v_begin_odd = readl_relaxed(priv->io_base +
1174 _REG(ENCI_VFIFO2VD_LINE_BOT_START));
1175 de_v_end_odd = de_v_begin_odd + mode->vdisplay;
1176
1177 writel_relaxed(de_v_begin_even,
1178 priv->io_base + _REG(ENCI_DE_V_BEGIN_EVEN));
1179 writel_relaxed(de_v_end_even,
1180 priv->io_base + _REG(ENCI_DE_V_END_EVEN));
1181 writel_relaxed(de_v_begin_odd,
1182 priv->io_base + _REG(ENCI_DE_V_BEGIN_ODD));
1183 writel_relaxed(de_v_end_odd,
1184 priv->io_base + _REG(ENCI_DE_V_END_ODD));
1185
1186 /* Program Hsync timing */
1187 hs_begin = de_h_end + front_porch_venc;
1188 if (de_h_end + front_porch_venc >= total_pixels_venc) {
1189 hs_begin -= total_pixels_venc;
1190 vs_adjust = 1;
1191 } else {
1192 hs_begin = de_h_end + front_porch_venc;
1193 vs_adjust = 0;
1194 }
1195
1196 hs_end = modulo(hs_begin + hsync_pixels_venc,
1197 total_pixels_venc);
1198 writel_relaxed(hs_begin,
1199 priv->io_base + _REG(ENCI_DVI_HSO_BEGIN));
1200 writel_relaxed(hs_end,
1201 priv->io_base + _REG(ENCI_DVI_HSO_END));
1202
1203 /* Program Vsync timing for even field */
1204 if (((de_v_end_odd - 1) + eof_lines + vs_adjust) >= lines_f1) {
1205 vs_bline_evn = (de_v_end_odd - 1)
1206 + eof_lines
1207 + vs_adjust
1208 - lines_f1;
1209 vs_eline_evn = vs_bline_evn + vsync_lines;
1210
1211 writel_relaxed(vs_bline_evn,
1212 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN));
1213
1214 writel_relaxed(vs_eline_evn,
1215 priv->io_base + _REG(ENCI_DVI_VSO_ELINE_EVN));
1216
1217 writel_relaxed(hs_begin,
1218 priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_EVN));
1219 writel_relaxed(hs_begin,
1220 priv->io_base + _REG(ENCI_DVI_VSO_END_EVN));
1221 } else {
1222 vs_bline_odd = (de_v_end_odd - 1)
1223 + eof_lines
1224 + vs_adjust;
1225
1226 writel_relaxed(vs_bline_odd,
1227 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD));
1228
1229 writel_relaxed(hs_begin,
1230 priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD));
1231
1232 if ((vs_bline_odd + vsync_lines) >= lines_f1) {
1233 vs_eline_evn = vs_bline_odd
1234 + vsync_lines
1235 - lines_f1;
1236
1237 writel_relaxed(vs_eline_evn, priv->io_base
1238 + _REG(ENCI_DVI_VSO_ELINE_EVN));
1239
1240 writel_relaxed(hs_begin, priv->io_base
1241 + _REG(ENCI_DVI_VSO_END_EVN));
1242 } else {
1243 vs_eline_odd = vs_bline_odd
1244 + vsync_lines;
1245
1246 writel_relaxed(vs_eline_odd, priv->io_base
1247 + _REG(ENCI_DVI_VSO_ELINE_ODD));
1248
1249 writel_relaxed(hs_begin, priv->io_base
1250 + _REG(ENCI_DVI_VSO_END_ODD));
1251 }
1252 }
1253
1254 /* Program Vsync timing for odd field */
1255 if (((de_v_end_even - 1) + (eof_lines + 1)) >= lines_f0) {
1256 vs_bline_odd = (de_v_end_even - 1)
1257 + (eof_lines + 1)
1258 - lines_f0;
1259 vs_eline_odd = vs_bline_odd + vsync_lines;
1260
1261 writel_relaxed(vs_bline_odd,
1262 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD));
1263
1264 writel_relaxed(vs_eline_odd,
1265 priv->io_base + _REG(ENCI_DVI_VSO_ELINE_ODD));
1266
1267 vso_begin_odd = modulo(hs_begin
1268 + (total_pixels_venc >> 1),
1269 total_pixels_venc);
1270
1271 writel_relaxed(vso_begin_odd,
1272 priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD));
1273 writel_relaxed(vso_begin_odd,
1274 priv->io_base + _REG(ENCI_DVI_VSO_END_ODD));
1275 } else {
1276 vs_bline_evn = (de_v_end_even - 1)
1277 + (eof_lines + 1);
1278
1279 writel_relaxed(vs_bline_evn,
1280 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN));
1281
1282 vso_begin_evn = modulo(hs_begin
1283 + (total_pixels_venc >> 1),
1284 total_pixels_venc);
1285
1286 writel_relaxed(vso_begin_evn, priv->io_base
1287 + _REG(ENCI_DVI_VSO_BEGIN_EVN));
1288
1289 if (vs_bline_evn + vsync_lines >= lines_f0) {
1290 vs_eline_odd = vs_bline_evn
1291 + vsync_lines
1292 - lines_f0;
1293
1294 writel_relaxed(vs_eline_odd, priv->io_base
1295 + _REG(ENCI_DVI_VSO_ELINE_ODD));
1296
1297 writel_relaxed(vso_begin_evn, priv->io_base
1298 + _REG(ENCI_DVI_VSO_END_ODD));
1299 } else {
1300 vs_eline_evn = vs_bline_evn + vsync_lines;
1301
1302 writel_relaxed(vs_eline_evn, priv->io_base
1303 + _REG(ENCI_DVI_VSO_ELINE_EVN));
1304
1305 writel_relaxed(vso_begin_evn, priv->io_base
1306 + _REG(ENCI_DVI_VSO_END_EVN));
1307 }
1308 }
1309 } else {
1310 writel_relaxed(vmode->encp.dvi_settings,
1311 priv->io_base + _REG(VENC_DVI_SETTING));
1312 writel_relaxed(vmode->encp.video_mode,
1313 priv->io_base + _REG(ENCP_VIDEO_MODE));
1314 writel_relaxed(vmode->encp.video_mode_adv,
1315 priv->io_base + _REG(ENCP_VIDEO_MODE_ADV));
1316 if (vmode->encp.video_prog_mode_present)
1317 writel_relaxed(vmode->encp.video_prog_mode,
1318 priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
1319 if (vmode->encp.video_sync_mode_present)
1320 writel_relaxed(vmode->encp.video_sync_mode,
1321 priv->io_base + _REG(ENCP_VIDEO_SYNC_MODE));
1322 if (vmode->encp.video_yc_dly_present)
1323 writel_relaxed(vmode->encp.video_yc_dly,
1324 priv->io_base + _REG(ENCP_VIDEO_YC_DLY));
1325 if (vmode->encp.video_rgb_ctrl_present)
1326 writel_relaxed(vmode->encp.video_rgb_ctrl,
1327 priv->io_base + _REG(ENCP_VIDEO_RGB_CTRL));
1328 if (vmode->encp.video_filt_ctrl_present)
1329 writel_relaxed(vmode->encp.video_filt_ctrl,
1330 priv->io_base + _REG(ENCP_VIDEO_FILT_CTRL));
1331 if (vmode->encp.video_ofld_voav_ofst_present)
1332 writel_relaxed(vmode->encp.video_ofld_voav_ofst,
1333 priv->io_base
1334 + _REG(ENCP_VIDEO_OFLD_VOAV_OFST));
1335 writel_relaxed(vmode->encp.yfp1_htime,
1336 priv->io_base + _REG(ENCP_VIDEO_YFP1_HTIME));
1337 writel_relaxed(vmode->encp.yfp2_htime,
1338 priv->io_base + _REG(ENCP_VIDEO_YFP2_HTIME));
1339 writel_relaxed(vmode->encp.max_pxcnt,
1340 priv->io_base + _REG(ENCP_VIDEO_MAX_PXCNT));
1341 writel_relaxed(vmode->encp.hspuls_begin,
1342 priv->io_base + _REG(ENCP_VIDEO_HSPULS_BEGIN));
1343 writel_relaxed(vmode->encp.hspuls_end,
1344 priv->io_base + _REG(ENCP_VIDEO_HSPULS_END));
1345 writel_relaxed(vmode->encp.hspuls_switch,
1346 priv->io_base + _REG(ENCP_VIDEO_HSPULS_SWITCH));
1347 writel_relaxed(vmode->encp.vspuls_begin,
1348 priv->io_base + _REG(ENCP_VIDEO_VSPULS_BEGIN));
1349 writel_relaxed(vmode->encp.vspuls_end,
1350 priv->io_base + _REG(ENCP_VIDEO_VSPULS_END));
1351 writel_relaxed(vmode->encp.vspuls_bline,
1352 priv->io_base + _REG(ENCP_VIDEO_VSPULS_BLINE));
1353 writel_relaxed(vmode->encp.vspuls_eline,
1354 priv->io_base + _REG(ENCP_VIDEO_VSPULS_ELINE));
1355 if (vmode->encp.eqpuls_begin_present)
1356 writel_relaxed(vmode->encp.eqpuls_begin,
1357 priv->io_base + _REG(ENCP_VIDEO_EQPULS_BEGIN));
1358 if (vmode->encp.eqpuls_end_present)
1359 writel_relaxed(vmode->encp.eqpuls_end,
1360 priv->io_base + _REG(ENCP_VIDEO_EQPULS_END));
1361 if (vmode->encp.eqpuls_bline_present)
1362 writel_relaxed(vmode->encp.eqpuls_bline,
1363 priv->io_base + _REG(ENCP_VIDEO_EQPULS_BLINE));
1364 if (vmode->encp.eqpuls_eline_present)
1365 writel_relaxed(vmode->encp.eqpuls_eline,
1366 priv->io_base + _REG(ENCP_VIDEO_EQPULS_ELINE));
1367 writel_relaxed(vmode->encp.havon_begin,
1368 priv->io_base + _REG(ENCP_VIDEO_HAVON_BEGIN));
1369 writel_relaxed(vmode->encp.havon_end,
1370 priv->io_base + _REG(ENCP_VIDEO_HAVON_END));
1371 writel_relaxed(vmode->encp.vavon_bline,
1372 priv->io_base + _REG(ENCP_VIDEO_VAVON_BLINE));
1373 writel_relaxed(vmode->encp.vavon_eline,
1374 priv->io_base + _REG(ENCP_VIDEO_VAVON_ELINE));
1375 writel_relaxed(vmode->encp.hso_begin,
1376 priv->io_base + _REG(ENCP_VIDEO_HSO_BEGIN));
1377 writel_relaxed(vmode->encp.hso_end,
1378 priv->io_base + _REG(ENCP_VIDEO_HSO_END));
1379 writel_relaxed(vmode->encp.vso_begin,
1380 priv->io_base + _REG(ENCP_VIDEO_VSO_BEGIN));
1381 writel_relaxed(vmode->encp.vso_end,
1382 priv->io_base + _REG(ENCP_VIDEO_VSO_END));
1383 writel_relaxed(vmode->encp.vso_bline,
1384 priv->io_base + _REG(ENCP_VIDEO_VSO_BLINE));
1385 if (vmode->encp.vso_eline_present)
1386 writel_relaxed(vmode->encp.vso_eline,
1387 priv->io_base + _REG(ENCP_VIDEO_VSO_ELINE));
1388 if (vmode->encp.sy_val_present)
1389 writel_relaxed(vmode->encp.sy_val,
1390 priv->io_base + _REG(ENCP_VIDEO_SY_VAL));
1391 if (vmode->encp.sy2_val_present)
1392 writel_relaxed(vmode->encp.sy2_val,
1393 priv->io_base + _REG(ENCP_VIDEO_SY2_VAL));
1394 writel_relaxed(vmode->encp.max_lncnt,
1395 priv->io_base + _REG(ENCP_VIDEO_MAX_LNCNT));
1396
1397 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN));
1398
1399 /* Set DE signal’s polarity is active high */
1400 writel_bits_relaxed(ENCP_VIDEO_MODE_DE_V_HIGH,
1401 ENCP_VIDEO_MODE_DE_V_HIGH,
1402 priv->io_base + _REG(ENCP_VIDEO_MODE));
1403
1404 /* Program DE timing */
1405 de_h_begin = modulo(readl_relaxed(priv->io_base +
1406 _REG(ENCP_VIDEO_HAVON_BEGIN))
1407 + venc_hdmi_latency,
1408 total_pixels_venc);
1409 de_h_end = modulo(de_h_begin + active_pixels_venc,
1410 total_pixels_venc);
1411
1412 writel_relaxed(de_h_begin,
1413 priv->io_base + _REG(ENCP_DE_H_BEGIN));
1414 writel_relaxed(de_h_end,
1415 priv->io_base + _REG(ENCP_DE_H_END));
1416
1417 /* Program DE timing for even field */
1418 de_v_begin_even = readl_relaxed(priv->io_base
1419 + _REG(ENCP_VIDEO_VAVON_BLINE));
1420 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1421 de_v_end_even = de_v_begin_even +
1422 (mode->vdisplay / 2);
1423 else
1424 de_v_end_even = de_v_begin_even + mode->vdisplay;
1425
1426 writel_relaxed(de_v_begin_even,
1427 priv->io_base + _REG(ENCP_DE_V_BEGIN_EVEN));
1428 writel_relaxed(de_v_end_even,
1429 priv->io_base + _REG(ENCP_DE_V_END_EVEN));
1430
1431 /* Program DE timing for odd field if needed */
1432 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1433 unsigned int ofld_voav_ofst =
1434 readl_relaxed(priv->io_base +
1435 _REG(ENCP_VIDEO_OFLD_VOAV_OFST));
1436 de_v_begin_odd = to_signed((ofld_voav_ofst & 0xf0) >> 4)
1437 + de_v_begin_even
1438 + ((mode->vtotal - 1) / 2);
1439 de_v_end_odd = de_v_begin_odd + (mode->vdisplay / 2);
1440
1441 writel_relaxed(de_v_begin_odd,
1442 priv->io_base + _REG(ENCP_DE_V_BEGIN_ODD));
1443 writel_relaxed(de_v_end_odd,
1444 priv->io_base + _REG(ENCP_DE_V_END_ODD));
1445 }
1446
1447 /* Program Hsync timing */
1448 if ((de_h_end + front_porch_venc) >= total_pixels_venc) {
1449 hs_begin = de_h_end
1450 + front_porch_venc
1451 - total_pixels_venc;
1452 vs_adjust = 1;
1453 } else {
1454 hs_begin = de_h_end
1455 + front_porch_venc;
1456 vs_adjust = 0;
1457 }
1458
1459 hs_end = modulo(hs_begin + hsync_pixels_venc,
1460 total_pixels_venc);
1461
1462 writel_relaxed(hs_begin,
1463 priv->io_base + _REG(ENCP_DVI_HSO_BEGIN));
1464 writel_relaxed(hs_end,
1465 priv->io_base + _REG(ENCP_DVI_HSO_END));
1466
1467 /* Program Vsync timing for even field */
1468 if (de_v_begin_even >=
1469 (sof_lines + vsync_lines + (1 - vs_adjust)))
1470 vs_bline_evn = de_v_begin_even
1471 - sof_lines
1472 - vsync_lines
1473 - (1 - vs_adjust);
1474 else
1475 vs_bline_evn = mode->vtotal
1476 + de_v_begin_even
1477 - sof_lines
1478 - vsync_lines
1479 - (1 - vs_adjust);
1480
1481 vs_eline_evn = modulo(vs_bline_evn + vsync_lines,
1482 mode->vtotal);
1483
1484 writel_relaxed(vs_bline_evn,
1485 priv->io_base + _REG(ENCP_DVI_VSO_BLINE_EVN));
1486 writel_relaxed(vs_eline_evn,
1487 priv->io_base + _REG(ENCP_DVI_VSO_ELINE_EVN));
1488
1489 vso_begin_evn = hs_begin;
1490 writel_relaxed(vso_begin_evn,
1491 priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_EVN));
1492 writel_relaxed(vso_begin_evn,
1493 priv->io_base + _REG(ENCP_DVI_VSO_END_EVN));
1494
1495 /* Program Vsync timing for odd field if needed */
1496 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1497 vs_bline_odd = (de_v_begin_odd - 1)
1498 - sof_lines
1499 - vsync_lines;
1500 vs_eline_odd = (de_v_begin_odd - 1)
1501 - vsync_lines;
1502 vso_begin_odd = modulo(hs_begin
1503 + (total_pixels_venc >> 1),
1504 total_pixels_venc);
1505
1506 writel_relaxed(vs_bline_odd,
1507 priv->io_base + _REG(ENCP_DVI_VSO_BLINE_ODD));
1508 writel_relaxed(vs_eline_odd,
1509 priv->io_base + _REG(ENCP_DVI_VSO_ELINE_ODD));
1510 writel_relaxed(vso_begin_odd,
1511 priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_ODD));
1512 writel_relaxed(vso_begin_odd,
1513 priv->io_base + _REG(ENCP_DVI_VSO_END_ODD));
1514 }
1515
1516 /* Select ENCP for VIU */
1517 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCP);
1518 }
1519
1520 /* Set VPU HDMI setting */
1521 /* Select ENCP or ENCI data to HDMI */
1522 if (use_enci)
1523 reg = VPU_HDMI_ENCI_DATA_TO_HDMI;
1524 else
1525 reg = VPU_HDMI_ENCP_DATA_TO_HDMI;
1526
1527 /* Invert polarity of HSYNC from VENC */
1528 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
1529 reg |= VPU_HDMI_INV_HSYNC;
1530
1531 /* Invert polarity of VSYNC from VENC */
1532 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
1533 reg |= VPU_HDMI_INV_VSYNC;
1534
1535 /* Output data format */
1536 reg |= ycrcb_map;
1537
1538 /*
1539 * Write rate to the async FIFO between VENC and HDMI.
1540 * One write every 2 wr_clk.
1541 */
1542 if (venc_repeat || yuv420_mode)
1543 reg |= VPU_HDMI_WR_RATE(2);
1544
1545 /*
1546 * Read rate to the async FIFO between VENC and HDMI.
1547 * One read every 2 wr_clk.
1548 */
1549 if (hdmi_repeat)
1550 reg |= VPU_HDMI_RD_RATE(2);
1551
1552 writel_relaxed(reg, priv->io_base + _REG(VPU_HDMI_SETTING));
1553
1554 priv->venc.hdmi_repeat = hdmi_repeat;
1555 priv->venc.venc_repeat = venc_repeat;
1556 priv->venc.hdmi_use_enci = use_enci;
1557
1558 priv->venc.current_mode = MESON_VENC_MODE_HDMI;
1559}
1560EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set);
1561
1562static unsigned short meson_encl_gamma_table[256] = {
1563 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
1564 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
1565 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188,
1566 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252,
1567 256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316,
1568 320, 324, 328, 332, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380,
1569 384, 388, 392, 396, 400, 404, 408, 412, 416, 420, 424, 428, 432, 436, 440, 444,
1570 448, 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, 496, 500, 504, 508,
1571 512, 516, 520, 524, 528, 532, 536, 540, 544, 548, 552, 556, 560, 564, 568, 572,
1572 576, 580, 584, 588, 592, 596, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636,
1573 640, 644, 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, 696, 700,
1574 704, 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, 748, 752, 756, 760, 764,
1575 768, 772, 776, 780, 784, 788, 792, 796, 800, 804, 808, 812, 816, 820, 824, 828,
1576 832, 836, 840, 844, 848, 852, 856, 860, 864, 868, 872, 876, 880, 884, 888, 892,
1577 896, 900, 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956,
1578 960, 964, 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020,
1579};
1580
1581static void meson_encl_set_gamma_table(struct meson_drm *priv, u16 *data,
1582 u32 rgb_mask)
1583{
1584 int i, ret;
1585 u32 reg;
1586
1587 writel_bits_relaxed(L_GAMMA_CNTL_PORT_EN, 0,
1588 priv->io_base + _REG(L_GAMMA_CNTL_PORT));
1589
1590 ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
1591 reg, reg & L_GAMMA_CNTL_PORT_ADR_RDY, 10, 10000);
1592 if (ret)
1593 pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
1594
1595 writel_relaxed(L_GAMMA_ADDR_PORT_AUTO_INC | rgb_mask |
1596 FIELD_PREP(L_GAMMA_ADDR_PORT_ADDR, 0),
1597 priv->io_base + _REG(L_GAMMA_ADDR_PORT));
1598
1599 for (i = 0; i < 256; i++) {
1600 ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
1601 reg, reg & L_GAMMA_CNTL_PORT_WR_RDY,
1602 10, 10000);
1603 if (ret)
1604 pr_warn_once("%s: GAMMA WR_RDY timeout\n", __func__);
1605
1606 writel_relaxed(data[i], priv->io_base + _REG(L_GAMMA_DATA_PORT));
1607 }
1608
1609 ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
1610 reg, reg & L_GAMMA_CNTL_PORT_ADR_RDY, 10, 10000);
1611 if (ret)
1612 pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
1613
1614 writel_relaxed(L_GAMMA_ADDR_PORT_AUTO_INC | rgb_mask |
1615 FIELD_PREP(L_GAMMA_ADDR_PORT_ADDR, 0x23),
1616 priv->io_base + _REG(L_GAMMA_ADDR_PORT));
1617}
1618
1619void meson_encl_load_gamma(struct meson_drm *priv)
1620{
1621 meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_R);
1622 meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_G);
1623 meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_B);
1624
1625 writel_bits_relaxed(L_GAMMA_CNTL_PORT_EN, L_GAMMA_CNTL_PORT_EN,
1626 priv->io_base + _REG(L_GAMMA_CNTL_PORT));
1627}
1628
1629void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
1630 const struct drm_display_mode *mode)
1631{
1632 unsigned int max_pxcnt;
1633 unsigned int max_lncnt;
1634 unsigned int havon_begin;
1635 unsigned int havon_end;
1636 unsigned int vavon_bline;
1637 unsigned int vavon_eline;
1638 unsigned int hso_begin;
1639 unsigned int hso_end;
1640 unsigned int vso_begin;
1641 unsigned int vso_end;
1642 unsigned int vso_bline;
1643 unsigned int vso_eline;
1644
1645 max_pxcnt = mode->htotal - 1;
1646 max_lncnt = mode->vtotal - 1;
1647 havon_begin = mode->htotal - mode->hsync_start;
1648 havon_end = havon_begin + mode->hdisplay - 1;
1649 vavon_bline = mode->vtotal - mode->vsync_start;
1650 vavon_eline = vavon_bline + mode->vdisplay - 1;
1651 hso_begin = 0;
1652 hso_end = mode->hsync_end - mode->hsync_start;
1653 vso_begin = 0;
1654 vso_end = 0;
1655 vso_bline = 0;
1656 vso_eline = mode->vsync_end - mode->vsync_start;
1657
1658 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCL);
1659
1660 writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
1661
1662 writel_relaxed(ENCL_PX_LN_CNT_SHADOW_EN, priv->io_base + _REG(ENCL_VIDEO_MODE));
1663 writel_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN |
1664 ENCL_VIDEO_MODE_ADV_GAIN_HDTV |
1665 ENCL_SEL_GAMMA_RGB_IN, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
1666
1667 writel_relaxed(ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER,
1668 priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL));
1669 writel_relaxed(max_pxcnt, priv->io_base + _REG(ENCL_VIDEO_MAX_PXCNT));
1670 writel_relaxed(max_lncnt, priv->io_base + _REG(ENCL_VIDEO_MAX_LNCNT));
1671 writel_relaxed(havon_begin, priv->io_base + _REG(ENCL_VIDEO_HAVON_BEGIN));
1672 writel_relaxed(havon_end, priv->io_base + _REG(ENCL_VIDEO_HAVON_END));
1673 writel_relaxed(vavon_bline, priv->io_base + _REG(ENCL_VIDEO_VAVON_BLINE));
1674 writel_relaxed(vavon_eline, priv->io_base + _REG(ENCL_VIDEO_VAVON_ELINE));
1675
1676 writel_relaxed(hso_begin, priv->io_base + _REG(ENCL_VIDEO_HSO_BEGIN));
1677 writel_relaxed(hso_end, priv->io_base + _REG(ENCL_VIDEO_HSO_END));
1678 writel_relaxed(vso_begin, priv->io_base + _REG(ENCL_VIDEO_VSO_BEGIN));
1679 writel_relaxed(vso_end, priv->io_base + _REG(ENCL_VIDEO_VSO_END));
1680 writel_relaxed(vso_bline, priv->io_base + _REG(ENCL_VIDEO_VSO_BLINE));
1681 writel_relaxed(vso_eline, priv->io_base + _REG(ENCL_VIDEO_VSO_ELINE));
1682 writel_relaxed(ENCL_VIDEO_RGBIN_RGB | ENCL_VIDEO_RGBIN_ZBLK,
1683 priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL));
1684
1685 /* default black pattern */
1686 writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL));
1687 writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y));
1688 writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB));
1689 writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR));
1690 writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN));
1691 writel_bits_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN, 0,
1692 priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
1693
1694 writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
1695
1696 writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR));
1697 writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR)); /* Magic value */
1698
1699 writel_relaxed(L_DITH_CNTL_DITH10_EN, priv->io_base + _REG(L_DITH_CNTL_ADDR));
1700
1701 /* DE signal for TTL */
1702 writel_relaxed(havon_begin, priv->io_base + _REG(L_OEH_HS_ADDR));
1703 writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEH_HE_ADDR));
1704 writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEH_VS_ADDR));
1705 writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEH_VE_ADDR));
1706
1707 /* DE signal for TTL */
1708 writel_relaxed(havon_begin, priv->io_base + _REG(L_OEV1_HS_ADDR));
1709 writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEV1_HE_ADDR));
1710 writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEV1_VS_ADDR));
1711 writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEV1_VE_ADDR));
1712
1713 /* Hsync signal for TTL */
1714 if (mode->flags & DRM_MODE_FLAG_PHSYNC) {
1715 writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HS_ADDR));
1716 writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HE_ADDR));
1717 } else {
1718 writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HS_ADDR));
1719 writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HE_ADDR));
1720 }
1721 writel_relaxed(0, priv->io_base + _REG(L_STH1_VS_ADDR));
1722 writel_relaxed(max_lncnt, priv->io_base + _REG(L_STH1_VE_ADDR));
1723
1724 /* Vsync signal for TTL */
1725 writel_relaxed(vso_begin, priv->io_base + _REG(L_STV1_HS_ADDR));
1726 writel_relaxed(vso_end, priv->io_base + _REG(L_STV1_HE_ADDR));
1727 if (mode->flags & DRM_MODE_FLAG_PVSYNC) {
1728 writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VS_ADDR));
1729 writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VE_ADDR));
1730 } else {
1731 writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VS_ADDR));
1732 writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VE_ADDR));
1733 }
1734
1735 /* DE signal */
1736 writel_relaxed(havon_begin, priv->io_base + _REG(L_DE_HS_ADDR));
1737 writel_relaxed(havon_end + 1, priv->io_base + _REG(L_DE_HE_ADDR));
1738 writel_relaxed(vavon_bline, priv->io_base + _REG(L_DE_VS_ADDR));
1739 writel_relaxed(vavon_eline, priv->io_base + _REG(L_DE_VE_ADDR));
1740
1741 /* Hsync signal */
1742 writel_relaxed(hso_begin, priv->io_base + _REG(L_HSYNC_HS_ADDR));
1743 writel_relaxed(hso_end, priv->io_base + _REG(L_HSYNC_HE_ADDR));
1744 writel_relaxed(0, priv->io_base + _REG(L_HSYNC_VS_ADDR));
1745 writel_relaxed(max_lncnt, priv->io_base + _REG(L_HSYNC_VE_ADDR));
1746
1747 /* Vsync signal */
1748 writel_relaxed(vso_begin, priv->io_base + _REG(L_VSYNC_HS_ADDR));
1749 writel_relaxed(vso_end, priv->io_base + _REG(L_VSYNC_HE_ADDR));
1750 writel_relaxed(vso_bline, priv->io_base + _REG(L_VSYNC_VS_ADDR));
1751 writel_relaxed(vso_eline, priv->io_base + _REG(L_VSYNC_VE_ADDR));
1752
1753 writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR));
1754 writel_relaxed(L_TCON_MISC_SEL_STV1 | L_TCON_MISC_SEL_STV2,
1755 priv->io_base + _REG(L_TCON_MISC_SEL_ADDR));
1756
1757 priv->venc.current_mode = MESON_VENC_MODE_MIPI_DSI;
1758}
1759EXPORT_SYMBOL_GPL(meson_venc_mipi_dsi_mode_set);
1760
1761void meson_venci_cvbs_mode_set(struct meson_drm *priv,
1762 struct meson_cvbs_enci_mode *mode)
1763{
1764 u32 reg;
1765
1766 if (mode->mode_tag == priv->venc.current_mode)
1767 return;
1768
1769 /* CVBS Filter settings */
1770 writel_relaxed(ENCI_CFILT_CMPT_SEL_HIGH | 0x10,
1771 priv->io_base + _REG(ENCI_CFILT_CTRL));
1772 writel_relaxed(ENCI_CFILT_CMPT_CR_DLY(2) |
1773 ENCI_CFILT_CMPT_CB_DLY(1),
1774 priv->io_base + _REG(ENCI_CFILT_CTRL2));
1775
1776 /* Digital Video Select : Interlace, clk27 clk, external */
1777 writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING));
1778
1779 /* Reset Video Mode */
1780 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE));
1781 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
1782
1783 /* Horizontal sync signal output */
1784 writel_relaxed(mode->hso_begin,
1785 priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN));
1786 writel_relaxed(mode->hso_end,
1787 priv->io_base + _REG(ENCI_SYNC_HSO_END));
1788
1789 /* Vertical Sync lines */
1790 writel_relaxed(mode->vso_even,
1791 priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN));
1792 writel_relaxed(mode->vso_odd,
1793 priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));
1794
1795 /* Macrovision max amplitude change */
1796 writel_relaxed(ENCI_MACV_MAX_AMP_ENABLE_CHANGE |
1797 ENCI_MACV_MAX_AMP_VAL(mode->macv_max_amp),
1798 priv->io_base + _REG(ENCI_MACV_MAX_AMP));
1799
1800 /* Video mode */
1801 writel_relaxed(mode->video_prog_mode,
1802 priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
1803 writel_relaxed(mode->video_mode,
1804 priv->io_base + _REG(ENCI_VIDEO_MODE));
1805
1806 /*
1807 * Advanced Video Mode :
1808 * Demux shifting 0x2
1809 * Blank line end at line17/22
1810 * High bandwidth Luma Filter
1811 * Low bandwidth Chroma Filter
1812 * Bypass luma low pass filter
1813 * No macrovision on CSYNC
1814 */
1815 writel_relaxed(ENCI_VIDEO_MODE_ADV_DMXMD(2) |
1816 ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 |
1817 ENCI_VIDEO_MODE_ADV_YBW_HIGH,
1818 priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
1819
1820 writel(mode->sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH));
1821
1822 /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
1823 writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE));
1824
1825 /* 0x3 Y, C, and Component Y delay */
1826 writel_relaxed(mode->yc_delay, priv->io_base + _REG(ENCI_YC_DELAY));
1827
1828 /* Timings */
1829 writel_relaxed(mode->pixel_start,
1830 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START));
1831 writel_relaxed(mode->pixel_end,
1832 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END));
1833
1834 writel_relaxed(mode->top_field_line_start,
1835 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START));
1836 writel_relaxed(mode->top_field_line_end,
1837 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END));
1838
1839 writel_relaxed(mode->bottom_field_line_start,
1840 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START));
1841 writel_relaxed(mode->bottom_field_line_end,
1842 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END));
1843
1844 /* Internal Venc, Internal VIU Sync, Internal Vencoder */
1845 writel_relaxed(0, priv->io_base + _REG(VENC_SYNC_ROUTE));
1846
1847 /* UNreset Interlaced TV Encoder */
1848 writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST));
1849
1850 /*
1851 * Enable Vfifo2vd and set Y_Cb_Y_Cr:
1852 * Corresponding value:
1853 * Y => 00 or 10
1854 * Cb => 01
1855 * Cr => 11
1856 * Ex: 0x4e => 01001110 would mean Cb/Y/Cr/Y
1857 */
1858 writel_relaxed(ENCI_VFIFO2VD_CTL_ENABLE |
1859 ENCI_VFIFO2VD_CTL_VD_SEL(0x4e),
1860 priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
1861
1862 /* Power UP Dacs */
1863 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_SETTING));
1864
1865 /* Video Upsampling */
1866 /*
1867 * CTRL0, CTRL1 and CTRL2:
1868 * Filter0: input data sample every 2 cloks
1869 * Filter1: filtering and upsample enable
1870 */
1871 reg = VENC_UPSAMPLE_CTRL_F0_2_CLK_RATIO | VENC_UPSAMPLE_CTRL_F1_EN |
1872 VENC_UPSAMPLE_CTRL_F1_UPSAMPLE_EN;
1873
1874 /*
1875 * Upsample CTRL0:
1876 * Interlace High Bandwidth Luma
1877 */
1878 writel_relaxed(VENC_UPSAMPLE_CTRL_INTERLACE_HIGH_LUMA | reg,
1879 priv->io_base + _REG(VENC_UPSAMPLE_CTRL0));
1880
1881 /*
1882 * Upsample CTRL1:
1883 * Interlace Pb
1884 */
1885 writel_relaxed(VENC_UPSAMPLE_CTRL_INTERLACE_PB | reg,
1886 priv->io_base + _REG(VENC_UPSAMPLE_CTRL1));
1887
1888 /*
1889 * Upsample CTRL2:
1890 * Interlace R
1891 */
1892 writel_relaxed(VENC_UPSAMPLE_CTRL_INTERLACE_PR | reg,
1893 priv->io_base + _REG(VENC_UPSAMPLE_CTRL2));
1894
1895 /* Select Interlace Y DACs */
1896 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL0));
1897 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL1));
1898 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL2));
1899 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL3));
1900 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL4));
1901 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL5));
1902
1903 /* Select ENCI for VIU */
1904 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);
1905
1906 /* Enable ENCI FIFO */
1907 writel_relaxed(VENC_VDAC_FIFO_EN_ENCI_ENABLE,
1908 priv->io_base + _REG(VENC_VDAC_FIFO_CTRL));
1909
1910 /* Select ENCI DACs 0, 1, 4, and 5 */
1911 writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_0));
1912 writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_1));
1913
1914 /* Interlace video enable */
1915 writel_relaxed(ENCI_VIDEO_EN_ENABLE,
1916 priv->io_base + _REG(ENCI_VIDEO_EN));
1917
1918 /* Configure Video Saturation / Contrast / Brightness / Hue */
1919 writel_relaxed(mode->video_saturation,
1920 priv->io_base + _REG(ENCI_VIDEO_SAT));
1921 writel_relaxed(mode->video_contrast,
1922 priv->io_base + _REG(ENCI_VIDEO_CONT));
1923 writel_relaxed(mode->video_brightness,
1924 priv->io_base + _REG(ENCI_VIDEO_BRIGHT));
1925 writel_relaxed(mode->video_hue,
1926 priv->io_base + _REG(ENCI_VIDEO_HUE));
1927
1928 /* Enable DAC0 Filter */
1929 writel_relaxed(VENC_VDAC_DAC0_FILT_CTRL0_EN,
1930 priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0));
1931 writel_relaxed(0xfc48, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL1));
1932
1933 /* 0 in Macrovision register 0 */
1934 writel_relaxed(0, priv->io_base + _REG(ENCI_MACV_N0));
1935
1936 /* Analog Synchronization and color burst value adjust */
1937 writel_relaxed(mode->analog_sync_adj,
1938 priv->io_base + _REG(ENCI_SYNC_ADJ));
1939
1940 priv->venc.current_mode = mode->mode_tag;
1941}
1942
1943/* Returns the current ENCI field polarity */
1944unsigned int meson_venci_get_field(struct meson_drm *priv)
1945{
1946 return readl_relaxed(priv->io_base + _REG(ENCI_INFO_READ)) & BIT(29);
1947}
1948
1949void meson_venc_enable_vsync(struct meson_drm *priv)
1950{
1951 switch (priv->venc.current_mode) {
1952 case MESON_VENC_MODE_MIPI_DSI:
1953 writel_relaxed(VENC_INTCTRL_ENCP_LNRST_INT_EN,
1954 priv->io_base + _REG(VENC_INTCTRL));
1955 break;
1956 default:
1957 writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
1958 priv->io_base + _REG(VENC_INTCTRL));
1959 }
1960 regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
1961}
1962
1963void meson_venc_disable_vsync(struct meson_drm *priv)
1964{
1965 regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0);
1966 writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL));
1967}
1968
1969void meson_venc_init(struct meson_drm *priv)
1970{
1971 /* Disable CVBS VDAC */
1972 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
1973 regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0);
1974 regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 8);
1975 } else {
1976 regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0);
1977 regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8);
1978 }
1979
1980 /* Power Down Dacs */
1981 writel_relaxed(0xff, priv->io_base + _REG(VENC_VDAC_SETTING));
1982
1983 /* Disable HDMI PHY */
1984 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
1985
1986 /* Disable HDMI */
1987 writel_bits_relaxed(VPU_HDMI_ENCI_DATA_TO_HDMI |
1988 VPU_HDMI_ENCP_DATA_TO_HDMI, 0,
1989 priv->io_base + _REG(VPU_HDMI_SETTING));
1990
1991 /* Disable all encoders */
1992 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
1993 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
1994 writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
1995
1996 /* Disable VSync IRQ */
1997 meson_venc_disable_vsync(priv);
1998
1999 priv->venc.current_mode = MESON_VENC_MODE_NONE;
2000}
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <drm/drmP.h>
23#include "meson_drv.h"
24#include "meson_venc.h"
25#include "meson_vpp.h"
26#include "meson_vclk.h"
27#include "meson_registers.h"
28
29/**
30 * DOC: Video Encoder
31 *
32 * VENC Handle the pixels encoding to the output formats.
33 * We handle the following encodings :
34 *
35 * - CVBS Encoding via the ENCI encoder and VDAC digital to analog converter
36 * - TMDS/HDMI Encoding via ENCI_DIV and ENCP
37 * - Setup of more clock rates for HDMI modes
38 *
39 * What is missing :
40 *
41 * - LCD Panel encoding via ENCL
42 * - TV Panel encoding via ENCT
43 *
44 * VENC paths :
45 *
46 * .. code::
47 *
48 * _____ _____ ____________________
49 * vd1---| |-| | | VENC /---------|----VDAC
50 * vd2---| VIU |-| VPP |-|-----ENCI/-ENCI_DVI-|-|
51 * osd1--| |-| | | \ | X--HDMI-TX
52 * osd2--|_____|-|_____| | |\-ENCP--ENCP_DVI-|-|
53 * | | |
54 * | \--ENCL-----------|----LVDS
55 * |____________________|
56 *
57 * The ENCI is designed for PAl or NTSC encoding and can go through the VDAC
58 * directly for CVBS encoding or through the ENCI_DVI encoder for HDMI.
59 * The ENCP is designed for Progressive encoding but can also generate
60 * 1080i interlaced pixels, and was initialy desined to encode pixels for
61 * VDAC to output RGB ou YUV analog outputs.
62 * It's output is only used through the ENCP_DVI encoder for HDMI.
63 * The ENCL LVDS encoder is not implemented.
64 *
65 * The ENCI and ENCP encoders needs specially defined parameters for each
66 * supported mode and thus cannot be determined from standard video timings.
67 *
68 * The ENCI end ENCP DVI encoders are more generic and can generate any timings
69 * from the pixel data generated by ENCI or ENCP, so can use the standard video
70 * timings are source for HW parameters.
71 */
72
73/* HHI Registers */
74#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
75#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
76#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */
77
78struct meson_cvbs_enci_mode meson_cvbs_enci_pal = {
79 .mode_tag = MESON_VENC_MODE_CVBS_PAL,
80 .hso_begin = 3,
81 .hso_end = 129,
82 .vso_even = 3,
83 .vso_odd = 260,
84 .macv_max_amp = 7,
85 .video_prog_mode = 0xff,
86 .video_mode = 0x13,
87 .sch_adjust = 0x28,
88 .yc_delay = 0x343,
89 .pixel_start = 251,
90 .pixel_end = 1691,
91 .top_field_line_start = 22,
92 .top_field_line_end = 310,
93 .bottom_field_line_start = 23,
94 .bottom_field_line_end = 311,
95 .video_saturation = 9,
96 .video_contrast = 0,
97 .video_brightness = 0,
98 .video_hue = 0,
99 .analog_sync_adj = 0x8080,
100};
101
102struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc = {
103 .mode_tag = MESON_VENC_MODE_CVBS_NTSC,
104 .hso_begin = 5,
105 .hso_end = 129,
106 .vso_even = 3,
107 .vso_odd = 260,
108 .macv_max_amp = 0xb,
109 .video_prog_mode = 0xf0,
110 .video_mode = 0x8,
111 .sch_adjust = 0x20,
112 .yc_delay = 0x333,
113 .pixel_start = 227,
114 .pixel_end = 1667,
115 .top_field_line_start = 18,
116 .top_field_line_end = 258,
117 .bottom_field_line_start = 19,
118 .bottom_field_line_end = 259,
119 .video_saturation = 18,
120 .video_contrast = 3,
121 .video_brightness = 0,
122 .video_hue = 0,
123 .analog_sync_adj = 0x9c00,
124};
125
126union meson_hdmi_venc_mode {
127 struct {
128 unsigned int mode_tag;
129 unsigned int hso_begin;
130 unsigned int hso_end;
131 unsigned int vso_even;
132 unsigned int vso_odd;
133 unsigned int macv_max_amp;
134 unsigned int video_prog_mode;
135 unsigned int video_mode;
136 unsigned int sch_adjust;
137 unsigned int yc_delay;
138 unsigned int pixel_start;
139 unsigned int pixel_end;
140 unsigned int top_field_line_start;
141 unsigned int top_field_line_end;
142 unsigned int bottom_field_line_start;
143 unsigned int bottom_field_line_end;
144 } enci;
145 struct {
146 unsigned int dvi_settings;
147 unsigned int video_mode;
148 unsigned int video_mode_adv;
149 unsigned int video_prog_mode;
150 bool video_prog_mode_present;
151 unsigned int video_sync_mode;
152 bool video_sync_mode_present;
153 unsigned int video_yc_dly;
154 bool video_yc_dly_present;
155 unsigned int video_rgb_ctrl;
156 bool video_rgb_ctrl_present;
157 unsigned int video_filt_ctrl;
158 bool video_filt_ctrl_present;
159 unsigned int video_ofld_voav_ofst;
160 bool video_ofld_voav_ofst_present;
161 unsigned int yfp1_htime;
162 unsigned int yfp2_htime;
163 unsigned int max_pxcnt;
164 unsigned int hspuls_begin;
165 unsigned int hspuls_end;
166 unsigned int hspuls_switch;
167 unsigned int vspuls_begin;
168 unsigned int vspuls_end;
169 unsigned int vspuls_bline;
170 unsigned int vspuls_eline;
171 unsigned int eqpuls_begin;
172 bool eqpuls_begin_present;
173 unsigned int eqpuls_end;
174 bool eqpuls_end_present;
175 unsigned int eqpuls_bline;
176 bool eqpuls_bline_present;
177 unsigned int eqpuls_eline;
178 bool eqpuls_eline_present;
179 unsigned int havon_begin;
180 unsigned int havon_end;
181 unsigned int vavon_bline;
182 unsigned int vavon_eline;
183 unsigned int hso_begin;
184 unsigned int hso_end;
185 unsigned int vso_begin;
186 unsigned int vso_end;
187 unsigned int vso_bline;
188 unsigned int vso_eline;
189 bool vso_eline_present;
190 unsigned int sy_val;
191 bool sy_val_present;
192 unsigned int sy2_val;
193 bool sy2_val_present;
194 unsigned int max_lncnt;
195 } encp;
196};
197
198union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = {
199 .enci = {
200 .hso_begin = 5,
201 .hso_end = 129,
202 .vso_even = 3,
203 .vso_odd = 260,
204 .macv_max_amp = 0x810b,
205 .video_prog_mode = 0xf0,
206 .video_mode = 0x8,
207 .sch_adjust = 0x20,
208 .yc_delay = 0,
209 .pixel_start = 227,
210 .pixel_end = 1667,
211 .top_field_line_start = 18,
212 .top_field_line_end = 258,
213 .bottom_field_line_start = 19,
214 .bottom_field_line_end = 259,
215 },
216};
217
218union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = {
219 .enci = {
220 .hso_begin = 3,
221 .hso_end = 129,
222 .vso_even = 3,
223 .vso_odd = 260,
224 .macv_max_amp = 8107,
225 .video_prog_mode = 0xff,
226 .video_mode = 0x13,
227 .sch_adjust = 0x28,
228 .yc_delay = 0x333,
229 .pixel_start = 251,
230 .pixel_end = 1691,
231 .top_field_line_start = 22,
232 .top_field_line_end = 310,
233 .bottom_field_line_start = 23,
234 .bottom_field_line_end = 311,
235 },
236};
237
238union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p = {
239 .encp = {
240 .dvi_settings = 0x21,
241 .video_mode = 0x4000,
242 .video_mode_adv = 0x9,
243 .video_prog_mode = 0,
244 .video_prog_mode_present = true,
245 .video_sync_mode = 7,
246 .video_sync_mode_present = true,
247 /* video_yc_dly */
248 /* video_rgb_ctrl */
249 .video_filt_ctrl = 0x2052,
250 .video_filt_ctrl_present = true,
251 /* video_ofld_voav_ofst */
252 .yfp1_htime = 244,
253 .yfp2_htime = 1630,
254 .max_pxcnt = 1715,
255 .hspuls_begin = 0x22,
256 .hspuls_end = 0xa0,
257 .hspuls_switch = 88,
258 .vspuls_begin = 0,
259 .vspuls_end = 1589,
260 .vspuls_bline = 0,
261 .vspuls_eline = 5,
262 .havon_begin = 249,
263 .havon_end = 1689,
264 .vavon_bline = 42,
265 .vavon_eline = 521,
266 /* eqpuls_begin */
267 /* eqpuls_end */
268 /* eqpuls_bline */
269 /* eqpuls_eline */
270 .hso_begin = 3,
271 .hso_end = 5,
272 .vso_begin = 3,
273 .vso_end = 5,
274 .vso_bline = 0,
275 /* vso_eline */
276 .sy_val = 8,
277 .sy_val_present = true,
278 .sy2_val = 0x1d8,
279 .sy2_val_present = true,
280 .max_lncnt = 524,
281 },
282};
283
284union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p = {
285 .encp = {
286 .dvi_settings = 0x21,
287 .video_mode = 0x4000,
288 .video_mode_adv = 0x9,
289 .video_prog_mode = 0,
290 .video_prog_mode_present = true,
291 .video_sync_mode = 7,
292 .video_sync_mode_present = true,
293 /* video_yc_dly */
294 /* video_rgb_ctrl */
295 .video_filt_ctrl = 0x52,
296 .video_filt_ctrl_present = true,
297 /* video_ofld_voav_ofst */
298 .yfp1_htime = 235,
299 .yfp2_htime = 1674,
300 .max_pxcnt = 1727,
301 .hspuls_begin = 0,
302 .hspuls_end = 0x80,
303 .hspuls_switch = 88,
304 .vspuls_begin = 0,
305 .vspuls_end = 1599,
306 .vspuls_bline = 0,
307 .vspuls_eline = 4,
308 .havon_begin = 235,
309 .havon_end = 1674,
310 .vavon_bline = 44,
311 .vavon_eline = 619,
312 /* eqpuls_begin */
313 /* eqpuls_end */
314 /* eqpuls_bline */
315 /* eqpuls_eline */
316 .hso_begin = 0x80,
317 .hso_end = 0,
318 .vso_begin = 0,
319 .vso_end = 5,
320 .vso_bline = 0,
321 /* vso_eline */
322 .sy_val = 8,
323 .sy_val_present = true,
324 .sy2_val = 0x1d8,
325 .sy2_val_present = true,
326 .max_lncnt = 624,
327 },
328};
329
330union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60 = {
331 .encp = {
332 .dvi_settings = 0x2029,
333 .video_mode = 0x4040,
334 .video_mode_adv = 0x19,
335 /* video_prog_mode */
336 /* video_sync_mode */
337 /* video_yc_dly */
338 /* video_rgb_ctrl */
339 /* video_filt_ctrl */
340 /* video_ofld_voav_ofst */
341 .yfp1_htime = 648,
342 .yfp2_htime = 3207,
343 .max_pxcnt = 3299,
344 .hspuls_begin = 80,
345 .hspuls_end = 240,
346 .hspuls_switch = 80,
347 .vspuls_begin = 688,
348 .vspuls_end = 3248,
349 .vspuls_bline = 4,
350 .vspuls_eline = 8,
351 .havon_begin = 648,
352 .havon_end = 3207,
353 .vavon_bline = 29,
354 .vavon_eline = 748,
355 /* eqpuls_begin */
356 /* eqpuls_end */
357 /* eqpuls_bline */
358 /* eqpuls_eline */
359 .hso_begin = 256,
360 .hso_end = 168,
361 .vso_begin = 168,
362 .vso_end = 256,
363 .vso_bline = 0,
364 .vso_eline = 5,
365 .vso_eline_present = true,
366 /* sy_val */
367 /* sy2_val */
368 .max_lncnt = 749,
369 },
370};
371
372union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50 = {
373 .encp = {
374 .dvi_settings = 0x202d,
375 .video_mode = 0x4040,
376 .video_mode_adv = 0x19,
377 .video_prog_mode = 0x100,
378 .video_prog_mode_present = true,
379 .video_sync_mode = 0x407,
380 .video_sync_mode_present = true,
381 .video_yc_dly = 0,
382 .video_yc_dly_present = true,
383 /* video_rgb_ctrl */
384 /* video_filt_ctrl */
385 /* video_ofld_voav_ofst */
386 .yfp1_htime = 648,
387 .yfp2_htime = 3207,
388 .max_pxcnt = 3959,
389 .hspuls_begin = 80,
390 .hspuls_end = 240,
391 .hspuls_switch = 80,
392 .vspuls_begin = 688,
393 .vspuls_end = 3248,
394 .vspuls_bline = 4,
395 .vspuls_eline = 8,
396 .havon_begin = 648,
397 .havon_end = 3207,
398 .vavon_bline = 29,
399 .vavon_eline = 748,
400 /* eqpuls_begin */
401 /* eqpuls_end */
402 /* eqpuls_bline */
403 /* eqpuls_eline */
404 .hso_begin = 128,
405 .hso_end = 208,
406 .vso_begin = 128,
407 .vso_end = 128,
408 .vso_bline = 0,
409 .vso_eline = 5,
410 .vso_eline_present = true,
411 /* sy_val */
412 /* sy2_val */
413 .max_lncnt = 749,
414 },
415};
416
417union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60 = {
418 .encp = {
419 .dvi_settings = 0x2029,
420 .video_mode = 0x5ffc,
421 .video_mode_adv = 0x19,
422 .video_prog_mode = 0x100,
423 .video_prog_mode_present = true,
424 .video_sync_mode = 0x207,
425 .video_sync_mode_present = true,
426 /* video_yc_dly */
427 /* video_rgb_ctrl */
428 /* video_filt_ctrl */
429 .video_ofld_voav_ofst = 0x11,
430 .video_ofld_voav_ofst_present = true,
431 .yfp1_htime = 516,
432 .yfp2_htime = 4355,
433 .max_pxcnt = 4399,
434 .hspuls_begin = 88,
435 .hspuls_end = 264,
436 .hspuls_switch = 88,
437 .vspuls_begin = 440,
438 .vspuls_end = 2200,
439 .vspuls_bline = 0,
440 .vspuls_eline = 4,
441 .havon_begin = 516,
442 .havon_end = 4355,
443 .vavon_bline = 20,
444 .vavon_eline = 559,
445 .eqpuls_begin = 2288,
446 .eqpuls_begin_present = true,
447 .eqpuls_end = 2464,
448 .eqpuls_end_present = true,
449 .eqpuls_bline = 0,
450 .eqpuls_bline_present = true,
451 .eqpuls_eline = 4,
452 .eqpuls_eline_present = true,
453 .hso_begin = 264,
454 .hso_end = 176,
455 .vso_begin = 88,
456 .vso_end = 88,
457 .vso_bline = 0,
458 .vso_eline = 5,
459 .vso_eline_present = true,
460 /* sy_val */
461 /* sy2_val */
462 .max_lncnt = 1124,
463 },
464};
465
466union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50 = {
467 .encp = {
468 .dvi_settings = 0x202d,
469 .video_mode = 0x5ffc,
470 .video_mode_adv = 0x19,
471 .video_prog_mode = 0x100,
472 .video_prog_mode_present = true,
473 .video_sync_mode = 0x7,
474 .video_sync_mode_present = true,
475 /* video_yc_dly */
476 /* video_rgb_ctrl */
477 /* video_filt_ctrl */
478 .video_ofld_voav_ofst = 0x11,
479 .video_ofld_voav_ofst_present = true,
480 .yfp1_htime = 526,
481 .yfp2_htime = 4365,
482 .max_pxcnt = 5279,
483 .hspuls_begin = 88,
484 .hspuls_end = 264,
485 .hspuls_switch = 88,
486 .vspuls_begin = 440,
487 .vspuls_end = 2200,
488 .vspuls_bline = 0,
489 .vspuls_eline = 4,
490 .havon_begin = 526,
491 .havon_end = 4365,
492 .vavon_bline = 20,
493 .vavon_eline = 559,
494 .eqpuls_begin = 2288,
495 .eqpuls_begin_present = true,
496 .eqpuls_end = 2464,
497 .eqpuls_end_present = true,
498 .eqpuls_bline = 0,
499 .eqpuls_bline_present = true,
500 .eqpuls_eline = 4,
501 .eqpuls_eline_present = true,
502 .hso_begin = 142,
503 .hso_end = 230,
504 .vso_begin = 142,
505 .vso_end = 142,
506 .vso_bline = 0,
507 .vso_eline = 5,
508 .vso_eline_present = true,
509 /* sy_val */
510 /* sy2_val */
511 .max_lncnt = 1124,
512 },
513};
514
515union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24 = {
516 .encp = {
517 .dvi_settings = 0xd,
518 .video_mode = 0x4040,
519 .video_mode_adv = 0x18,
520 .video_prog_mode = 0x100,
521 .video_prog_mode_present = true,
522 .video_sync_mode = 0x7,
523 .video_sync_mode_present = true,
524 .video_yc_dly = 0,
525 .video_yc_dly_present = true,
526 .video_rgb_ctrl = 2,
527 .video_rgb_ctrl_present = true,
528 .video_filt_ctrl = 0x1052,
529 .video_filt_ctrl_present = true,
530 /* video_ofld_voav_ofst */
531 .yfp1_htime = 271,
532 .yfp2_htime = 2190,
533 .max_pxcnt = 2749,
534 .hspuls_begin = 44,
535 .hspuls_end = 132,
536 .hspuls_switch = 44,
537 .vspuls_begin = 220,
538 .vspuls_end = 2140,
539 .vspuls_bline = 0,
540 .vspuls_eline = 4,
541 .havon_begin = 271,
542 .havon_end = 2190,
543 .vavon_bline = 41,
544 .vavon_eline = 1120,
545 /* eqpuls_begin */
546 /* eqpuls_end */
547 .eqpuls_bline = 0,
548 .eqpuls_bline_present = true,
549 .eqpuls_eline = 4,
550 .eqpuls_eline_present = true,
551 .hso_begin = 79,
552 .hso_end = 123,
553 .vso_begin = 79,
554 .vso_end = 79,
555 .vso_bline = 0,
556 .vso_eline = 5,
557 .vso_eline_present = true,
558 /* sy_val */
559 /* sy2_val */
560 .max_lncnt = 1124,
561 },
562};
563
564union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30 = {
565 .encp = {
566 .dvi_settings = 0x1,
567 .video_mode = 0x4040,
568 .video_mode_adv = 0x18,
569 .video_prog_mode = 0x100,
570 .video_prog_mode_present = true,
571 /* video_sync_mode */
572 /* video_yc_dly */
573 /* video_rgb_ctrl */
574 .video_filt_ctrl = 0x1052,
575 .video_filt_ctrl_present = true,
576 /* video_ofld_voav_ofst */
577 .yfp1_htime = 140,
578 .yfp2_htime = 2060,
579 .max_pxcnt = 2199,
580 .hspuls_begin = 2156,
581 .hspuls_end = 44,
582 .hspuls_switch = 44,
583 .vspuls_begin = 140,
584 .vspuls_end = 2059,
585 .vspuls_bline = 0,
586 .vspuls_eline = 4,
587 .havon_begin = 148,
588 .havon_end = 2067,
589 .vavon_bline = 41,
590 .vavon_eline = 1120,
591 /* eqpuls_begin */
592 /* eqpuls_end */
593 /* eqpuls_bline */
594 /* eqpuls_eline */
595 .hso_begin = 44,
596 .hso_end = 2156,
597 .vso_begin = 2100,
598 .vso_end = 2164,
599 .vso_bline = 0,
600 .vso_eline = 5,
601 .vso_eline_present = true,
602 /* sy_val */
603 /* sy2_val */
604 .max_lncnt = 1124,
605 },
606};
607
608union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50 = {
609 .encp = {
610 .dvi_settings = 0xd,
611 .video_mode = 0x4040,
612 .video_mode_adv = 0x18,
613 .video_prog_mode = 0x100,
614 .video_prog_mode_present = true,
615 .video_sync_mode = 0x7,
616 .video_sync_mode_present = true,
617 .video_yc_dly = 0,
618 .video_yc_dly_present = true,
619 .video_rgb_ctrl = 2,
620 .video_rgb_ctrl_present = true,
621 /* video_filt_ctrl */
622 /* video_ofld_voav_ofst */
623 .yfp1_htime = 271,
624 .yfp2_htime = 2190,
625 .max_pxcnt = 2639,
626 .hspuls_begin = 44,
627 .hspuls_end = 132,
628 .hspuls_switch = 44,
629 .vspuls_begin = 220,
630 .vspuls_end = 2140,
631 .vspuls_bline = 0,
632 .vspuls_eline = 4,
633 .havon_begin = 271,
634 .havon_end = 2190,
635 .vavon_bline = 41,
636 .vavon_eline = 1120,
637 /* eqpuls_begin */
638 /* eqpuls_end */
639 .eqpuls_bline = 0,
640 .eqpuls_bline_present = true,
641 .eqpuls_eline = 4,
642 .eqpuls_eline_present = true,
643 .hso_begin = 79,
644 .hso_end = 123,
645 .vso_begin = 79,
646 .vso_end = 79,
647 .vso_bline = 0,
648 .vso_eline = 5,
649 .vso_eline_present = true,
650 /* sy_val */
651 /* sy2_val */
652 .max_lncnt = 1124,
653 },
654};
655
656union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
657 .encp = {
658 .dvi_settings = 0x1,
659 .video_mode = 0x4040,
660 .video_mode_adv = 0x18,
661 .video_prog_mode = 0x100,
662 .video_prog_mode_present = true,
663 /* video_sync_mode */
664 /* video_yc_dly */
665 /* video_rgb_ctrl */
666 .video_filt_ctrl = 0x1052,
667 .video_filt_ctrl_present = true,
668 /* video_ofld_voav_ofst */
669 .yfp1_htime = 140,
670 .yfp2_htime = 2060,
671 .max_pxcnt = 2199,
672 .hspuls_begin = 2156,
673 .hspuls_end = 44,
674 .hspuls_switch = 44,
675 .vspuls_begin = 140,
676 .vspuls_end = 2059,
677 .vspuls_bline = 0,
678 .vspuls_eline = 4,
679 .havon_begin = 148,
680 .havon_end = 2067,
681 .vavon_bline = 41,
682 .vavon_eline = 1120,
683 /* eqpuls_begin */
684 /* eqpuls_end */
685 /* eqpuls_bline */
686 /* eqpuls_eline */
687 .hso_begin = 44,
688 .hso_end = 2156,
689 .vso_begin = 2100,
690 .vso_end = 2164,
691 .vso_bline = 0,
692 .vso_eline = 5,
693 .vso_eline_present = true,
694 /* sy_val */
695 /* sy2_val */
696 .max_lncnt = 1124,
697 },
698};
699
700union meson_hdmi_venc_mode meson_hdmi_encp_mode_640x480_60 = {
701 .encp = {
702 .dvi_settings = 0x21,
703 .video_mode = 0x4040,
704 .video_mode_adv = 0x18,
705 /* video_prog_mode */
706 /* video_sync_mode */
707 /* video_yc_dly */
708 /* video_rgb_ctrl */
709 /* video_filt_ctrl */
710 /* video_ofld_voav_ofst */
711 /* yfp1_htime */
712 /* yfp2_htime */
713 .max_pxcnt = 0x31f,
714 /* hspuls_begin */
715 /* hspuls_end */
716 /* hspuls_switch */
717 /* vspuls_begin */
718 /* vspuls_end */
719 /* vspuls_bline */
720 /* vspuls_eline */
721 .havon_begin = 0x90,
722 .havon_end = 0x30f,
723 .vavon_bline = 0x23,
724 .vavon_eline = 0x202,
725 /* eqpuls_begin */
726 /* eqpuls_end */
727 /* eqpuls_bline */
728 /* eqpuls_eline */
729 .hso_begin = 0,
730 .hso_end = 0x60,
731 .vso_begin = 0x1e,
732 .vso_end = 0x32,
733 .vso_bline = 0,
734 .vso_eline = 2,
735 .vso_eline_present = true,
736 /* sy_val */
737 /* sy2_val */
738 .max_lncnt = 0x20c,
739 },
740};
741
742union meson_hdmi_venc_mode meson_hdmi_encp_mode_800x600_60 = {
743 .encp = {
744 .dvi_settings = 0x21,
745 .video_mode = 0x4040,
746 .video_mode_adv = 0x18,
747 /* video_prog_mode */
748 /* video_sync_mode */
749 /* video_yc_dly */
750 /* video_rgb_ctrl */
751 /* video_filt_ctrl */
752 /* video_ofld_voav_ofst */
753 /* yfp1_htime */
754 /* yfp2_htime */
755 .max_pxcnt = 0x41f,
756 /* hspuls_begin */
757 /* hspuls_end */
758 /* hspuls_switch */
759 /* vspuls_begin */
760 /* vspuls_end */
761 /* vspuls_bline */
762 /* vspuls_eline */
763 .havon_begin = 0xD8,
764 .havon_end = 0x3f7,
765 .vavon_bline = 0x1b,
766 .vavon_eline = 0x272,
767 /* eqpuls_begin */
768 /* eqpuls_end */
769 /* eqpuls_bline */
770 /* eqpuls_eline */
771 .hso_begin = 0,
772 .hso_end = 0x80,
773 .vso_begin = 0x1e,
774 .vso_end = 0x32,
775 .vso_bline = 0,
776 .vso_eline = 4,
777 .vso_eline_present = true,
778 /* sy_val */
779 /* sy2_val */
780 .max_lncnt = 0x273,
781 },
782};
783
784union meson_hdmi_venc_mode meson_hdmi_encp_mode_1024x768_60 = {
785 .encp = {
786 .dvi_settings = 0x21,
787 .video_mode = 0x4040,
788 .video_mode_adv = 0x18,
789 /* video_prog_mode */
790 /* video_sync_mode */
791 /* video_yc_dly */
792 /* video_rgb_ctrl */
793 /* video_filt_ctrl */
794 /* video_ofld_voav_ofst */
795 /* yfp1_htime */
796 /* yfp2_htime */
797 .max_pxcnt = 1343,
798 /* hspuls_begin */
799 /* hspuls_end */
800 /* hspuls_switch */
801 /* vspuls_begin */
802 /* vspuls_end */
803 /* vspuls_bline */
804 /* vspuls_eline */
805 .havon_begin = 296,
806 .havon_end = 1319,
807 .vavon_bline = 35,
808 .vavon_eline = 802,
809 /* eqpuls_begin */
810 /* eqpuls_end */
811 /* eqpuls_bline */
812 /* eqpuls_eline */
813 .hso_begin = 0,
814 .hso_end = 136,
815 .vso_begin = 30,
816 .vso_end = 50,
817 .vso_bline = 0,
818 .vso_eline = 6,
819 .vso_eline_present = true,
820 /* sy_val */
821 /* sy2_val */
822 .max_lncnt = 805,
823 },
824};
825
826union meson_hdmi_venc_mode meson_hdmi_encp_mode_1152x864_75 = {
827 .encp = {
828 .dvi_settings = 0x21,
829 .video_mode = 0x4040,
830 .video_mode_adv = 0x18,
831 /* video_prog_mode */
832 /* video_sync_mode */
833 /* video_yc_dly */
834 /* video_rgb_ctrl */
835 /* video_filt_ctrl */
836 /* video_ofld_voav_ofst */
837 /* yfp1_htime */
838 /* yfp2_htime */
839 .max_pxcnt = 0x63f,
840 /* hspuls_begin */
841 /* hspuls_end */
842 /* hspuls_switch */
843 /* vspuls_begin */
844 /* vspuls_end */
845 /* vspuls_bline */
846 /* vspuls_eline */
847 .havon_begin = 0x180,
848 .havon_end = 0x5ff,
849 .vavon_bline = 0x23,
850 .vavon_eline = 0x382,
851 /* eqpuls_begin */
852 /* eqpuls_end */
853 /* eqpuls_bline */
854 /* eqpuls_eline */
855 .hso_begin = 0,
856 .hso_end = 0x80,
857 .vso_begin = 0x1e,
858 .vso_end = 0x32,
859 .vso_bline = 0,
860 .vso_eline = 3,
861 .vso_eline_present = true,
862 /* sy_val */
863 /* sy2_val */
864 .max_lncnt = 0x383,
865 },
866};
867
868union meson_hdmi_venc_mode meson_hdmi_encp_mode_1280x1024_60 = {
869 .encp = {
870 .dvi_settings = 0x21,
871 .video_mode = 0x4040,
872 .video_mode_adv = 0x18,
873 /* video_prog_mode */
874 /* video_sync_mode */
875 /* video_yc_dly */
876 /* video_rgb_ctrl */
877 /* video_filt_ctrl */
878 /* video_ofld_voav_ofst */
879 /* yfp1_htime */
880 /* yfp2_htime */
881 .max_pxcnt = 0x697,
882 /* hspuls_begin */
883 /* hspuls_end */
884 /* hspuls_switch */
885 /* vspuls_begin */
886 /* vspuls_end */
887 /* vspuls_bline */
888 /* vspuls_eline */
889 .havon_begin = 0x168,
890 .havon_end = 0x667,
891 .vavon_bline = 0x29,
892 .vavon_eline = 0x428,
893 /* eqpuls_begin */
894 /* eqpuls_end */
895 /* eqpuls_bline */
896 /* eqpuls_eline */
897 .hso_begin = 0,
898 .hso_end = 0x70,
899 .vso_begin = 0x1e,
900 .vso_end = 0x32,
901 .vso_bline = 0,
902 .vso_eline = 3,
903 .vso_eline_present = true,
904 /* sy_val */
905 /* sy2_val */
906 .max_lncnt = 0x429,
907 },
908};
909
910union meson_hdmi_venc_mode meson_hdmi_encp_mode_1600x1200_60 = {
911 .encp = {
912 .dvi_settings = 0x21,
913 .video_mode = 0x4040,
914 .video_mode_adv = 0x18,
915 /* video_prog_mode */
916 /* video_sync_mode */
917 /* video_yc_dly */
918 /* video_rgb_ctrl */
919 /* video_filt_ctrl */
920 /* video_ofld_voav_ofst */
921 /* yfp1_htime */
922 /* yfp2_htime */
923 .max_pxcnt = 0x86f,
924 /* hspuls_begin */
925 /* hspuls_end */
926 /* hspuls_switch */
927 /* vspuls_begin */
928 /* vspuls_end */
929 /* vspuls_bline */
930 /* vspuls_eline */
931 .havon_begin = 0x1f0,
932 .havon_end = 0x82f,
933 .vavon_bline = 0x31,
934 .vavon_eline = 0x4e0,
935 /* eqpuls_begin */
936 /* eqpuls_end */
937 /* eqpuls_bline */
938 /* eqpuls_eline */
939 .hso_begin = 0,
940 .hso_end = 0xc0,
941 .vso_begin = 0x1e,
942 .vso_end = 0x32,
943 .vso_bline = 0,
944 .vso_eline = 3,
945 .vso_eline_present = true,
946 /* sy_val */
947 /* sy2_val */
948 .max_lncnt = 0x4e1,
949 },
950};
951
952struct meson_hdmi_venc_dmt_mode {
953 struct drm_display_mode drm_mode;
954 union meson_hdmi_venc_mode *mode;
955} meson_hdmi_venc_dmt_modes[] = {
956 /* 640x480@60Hz */
957 {
958 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
959 752, 800, 0, 480, 490, 492, 525, 0,
960 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
961 &meson_hdmi_encp_mode_640x480_60,
962 },
963 /* 800x600@60Hz */
964 {
965 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
966 968, 1056, 0, 600, 601, 605, 628, 0,
967 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
968 &meson_hdmi_encp_mode_800x600_60,
969 },
970 /* 1024x768@60Hz */
971 {
972 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024,
973 1048, 1184, 1344, 0, 768, 771, 777, 806, 0,
974 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
975 &meson_hdmi_encp_mode_1024x768_60,
976 },
977 /* 1152x864@75Hz */
978 {
979 { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152,
980 1216, 1344, 1600, 0, 864, 865, 868, 900, 0,
981 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
982 &meson_hdmi_encp_mode_1152x864_75,
983 },
984 /* 1280x1024@60Hz */
985 {
986 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280,
987 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
988 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
989 &meson_hdmi_encp_mode_1280x1024_60,
990 },
991 /* 1600x1200@60Hz */
992 {
993 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600,
994 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
995 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
996 &meson_hdmi_encp_mode_1600x1200_60,
997 },
998 /* 1920x1080@60Hz */
999 {
1000 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920,
1001 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
1002 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
1003 &meson_hdmi_encp_mode_1080p60
1004 },
1005 { }, /* sentinel */
1006};
1007
1008struct meson_hdmi_venc_vic_mode {
1009 unsigned int vic;
1010 union meson_hdmi_venc_mode *mode;
1011} meson_hdmi_venc_vic_modes[] = {
1012 { 6, &meson_hdmi_enci_mode_480i },
1013 { 7, &meson_hdmi_enci_mode_480i },
1014 { 21, &meson_hdmi_enci_mode_576i },
1015 { 22, &meson_hdmi_enci_mode_576i },
1016 { 2, &meson_hdmi_encp_mode_480p },
1017 { 3, &meson_hdmi_encp_mode_480p },
1018 { 17, &meson_hdmi_encp_mode_576p },
1019 { 18, &meson_hdmi_encp_mode_576p },
1020 { 4, &meson_hdmi_encp_mode_720p60 },
1021 { 19, &meson_hdmi_encp_mode_720p50 },
1022 { 5, &meson_hdmi_encp_mode_1080i60 },
1023 { 20, &meson_hdmi_encp_mode_1080i50 },
1024 { 32, &meson_hdmi_encp_mode_1080p24 },
1025 { 34, &meson_hdmi_encp_mode_1080p30 },
1026 { 31, &meson_hdmi_encp_mode_1080p50 },
1027 { 16, &meson_hdmi_encp_mode_1080p60 },
1028 { 0, NULL}, /* sentinel */
1029};
1030
1031static signed int to_signed(unsigned int a)
1032{
1033 if (a <= 7)
1034 return a;
1035 else
1036 return a - 16;
1037}
1038
1039static unsigned long modulo(unsigned long a, unsigned long b)
1040{
1041 if (a >= b)
1042 return a - b;
1043 else
1044 return a;
1045}
1046
1047bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode)
1048{
1049 struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes;
1050
1051 while (vmode->mode) {
1052 if (drm_mode_equal(&vmode->drm_mode, mode))
1053 return true;
1054 vmode++;
1055 }
1056
1057 return false;
1058}
1059EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode);
1060
1061bool meson_venc_hdmi_supported_vic(int vic)
1062{
1063 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
1064
1065 while (vmode->vic && vmode->mode) {
1066 if (vmode->vic == vic)
1067 return true;
1068 vmode++;
1069 }
1070
1071 return false;
1072}
1073EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic);
1074
1075static union meson_hdmi_venc_mode
1076*meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode)
1077{
1078 struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes;
1079
1080 while (vmode->mode) {
1081 if (drm_mode_equal(&vmode->drm_mode, mode))
1082 return vmode->mode;
1083 vmode++;
1084 }
1085
1086 return NULL;
1087}
1088
1089static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic)
1090{
1091 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
1092
1093 while (vmode->vic && vmode->mode) {
1094 if (vmode->vic == vic)
1095 return vmode->mode;
1096 vmode++;
1097 }
1098
1099 return NULL;
1100}
1101
1102bool meson_venc_hdmi_venc_repeat(int vic)
1103{
1104 /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
1105 if (vic == 6 || vic == 7 || /* 480i */
1106 vic == 21 || vic == 22 || /* 576i */
1107 vic == 17 || vic == 18 || /* 576p */
1108 vic == 2 || vic == 3 || /* 480p */
1109 vic == 4 || /* 720p60 */
1110 vic == 19 || /* 720p50 */
1111 vic == 5 || /* 1080i60 */
1112 vic == 20) /* 1080i50 */
1113 return true;
1114
1115 return false;
1116}
1117EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat);
1118
1119void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
1120 struct drm_display_mode *mode)
1121{
1122 union meson_hdmi_venc_mode *vmode = NULL;
1123 bool use_enci = false;
1124 bool venc_repeat = false;
1125 bool hdmi_repeat = false;
1126 unsigned int venc_hdmi_latency = 2;
1127 unsigned long total_pixels_venc = 0;
1128 unsigned long active_pixels_venc = 0;
1129 unsigned long front_porch_venc = 0;
1130 unsigned long hsync_pixels_venc = 0;
1131 unsigned long de_h_begin = 0;
1132 unsigned long de_h_end = 0;
1133 unsigned long de_v_begin_even = 0;
1134 unsigned long de_v_end_even = 0;
1135 unsigned long de_v_begin_odd = 0;
1136 unsigned long de_v_end_odd = 0;
1137 unsigned long hs_begin = 0;
1138 unsigned long hs_end = 0;
1139 unsigned long vs_adjust = 0;
1140 unsigned long vs_bline_evn = 0;
1141 unsigned long vs_eline_evn = 0;
1142 unsigned long vs_bline_odd = 0;
1143 unsigned long vs_eline_odd = 0;
1144 unsigned long vso_begin_evn = 0;
1145 unsigned long vso_begin_odd = 0;
1146 unsigned int eof_lines;
1147 unsigned int sof_lines;
1148 unsigned int vsync_lines;
1149
1150 if (meson_venc_hdmi_supported_vic(vic))
1151 vmode = meson_venc_hdmi_get_vic_vmode(vic);
1152 else
1153 vmode = meson_venc_hdmi_get_dmt_vmode(mode);
1154 if (!vmode) {
1155 dev_err(priv->dev, "%s: Fatal Error, unsupported mode "
1156 DRM_MODE_FMT "\n", __func__, DRM_MODE_ARG(mode));
1157 return;
1158 }
1159
1160 /* Use VENCI for 480i and 576i and double HDMI pixels */
1161 if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
1162 hdmi_repeat = true;
1163 use_enci = true;
1164 venc_hdmi_latency = 1;
1165 }
1166
1167 /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
1168 if (meson_venc_hdmi_venc_repeat(vic))
1169 venc_repeat = true;
1170
1171 eof_lines = mode->vsync_start - mode->vdisplay;
1172 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1173 eof_lines /= 2;
1174 sof_lines = mode->vtotal - mode->vsync_end;
1175 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1176 sof_lines /= 2;
1177 vsync_lines = mode->vsync_end - mode->vsync_start;
1178 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1179 vsync_lines /= 2;
1180
1181 total_pixels_venc = mode->htotal;
1182 if (hdmi_repeat)
1183 total_pixels_venc /= 2;
1184 if (venc_repeat)
1185 total_pixels_venc *= 2;
1186
1187 active_pixels_venc = mode->hdisplay;
1188 if (hdmi_repeat)
1189 active_pixels_venc /= 2;
1190 if (venc_repeat)
1191 active_pixels_venc *= 2;
1192
1193 front_porch_venc = (mode->hsync_start - mode->hdisplay);
1194 if (hdmi_repeat)
1195 front_porch_venc /= 2;
1196 if (venc_repeat)
1197 front_porch_venc *= 2;
1198
1199 hsync_pixels_venc = (mode->hsync_end - mode->hsync_start);
1200 if (hdmi_repeat)
1201 hsync_pixels_venc /= 2;
1202 if (venc_repeat)
1203 hsync_pixels_venc *= 2;
1204
1205 /* Disable VDACs */
1206 writel_bits_relaxed(0xff, 0xff,
1207 priv->io_base + _REG(VENC_VDAC_SETTING));
1208
1209 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
1210 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
1211
1212 if (use_enci) {
1213 unsigned int lines_f0;
1214 unsigned int lines_f1;
1215
1216 /* CVBS Filter settings */
1217 writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL));
1218 writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2));
1219
1220 /* Digital Video Select : Interlace, clk27 clk, external */
1221 writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING));
1222
1223 /* Reset Video Mode */
1224 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE));
1225 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
1226
1227 /* Horizontal sync signal output */
1228 writel_relaxed(vmode->enci.hso_begin,
1229 priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN));
1230 writel_relaxed(vmode->enci.hso_end,
1231 priv->io_base + _REG(ENCI_SYNC_HSO_END));
1232
1233 /* Vertical Sync lines */
1234 writel_relaxed(vmode->enci.vso_even,
1235 priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN));
1236 writel_relaxed(vmode->enci.vso_odd,
1237 priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));
1238
1239 /* Macrovision max amplitude change */
1240 writel_relaxed(vmode->enci.macv_max_amp,
1241 priv->io_base + _REG(ENCI_MACV_MAX_AMP));
1242
1243 /* Video mode */
1244 writel_relaxed(vmode->enci.video_prog_mode,
1245 priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
1246 writel_relaxed(vmode->enci.video_mode,
1247 priv->io_base + _REG(ENCI_VIDEO_MODE));
1248
1249 /* Advanced Video Mode :
1250 * Demux shifting 0x2
1251 * Blank line end at line17/22
1252 * High bandwidth Luma Filter
1253 * Low bandwidth Chroma Filter
1254 * Bypass luma low pass filter
1255 * No macrovision on CSYNC
1256 */
1257 writel_relaxed(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
1258
1259 writel(vmode->enci.sch_adjust,
1260 priv->io_base + _REG(ENCI_VIDEO_SCH));
1261
1262 /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
1263 writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE));
1264
1265 if (vmode->enci.yc_delay)
1266 writel_relaxed(vmode->enci.yc_delay,
1267 priv->io_base + _REG(ENCI_YC_DELAY));
1268
1269
1270 /* UNreset Interlaced TV Encoder */
1271 writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST));
1272
1273 /* Enable Vfifo2vd, Y_Cb_Y_Cr select */
1274 writel_relaxed(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
1275
1276 /* Timings */
1277 writel_relaxed(vmode->enci.pixel_start,
1278 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START));
1279 writel_relaxed(vmode->enci.pixel_end,
1280 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END));
1281
1282 writel_relaxed(vmode->enci.top_field_line_start,
1283 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START));
1284 writel_relaxed(vmode->enci.top_field_line_end,
1285 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END));
1286
1287 writel_relaxed(vmode->enci.bottom_field_line_start,
1288 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START));
1289 writel_relaxed(vmode->enci.bottom_field_line_end,
1290 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END));
1291
1292 /* Select ENCI for VIU */
1293 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);
1294
1295 /* Interlace video enable */
1296 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN));
1297
1298 lines_f0 = mode->vtotal >> 1;
1299 lines_f1 = lines_f0 + 1;
1300
1301 de_h_begin = modulo(readl_relaxed(priv->io_base +
1302 _REG(ENCI_VFIFO2VD_PIXEL_START))
1303 + venc_hdmi_latency,
1304 total_pixels_venc);
1305 de_h_end = modulo(de_h_begin + active_pixels_venc,
1306 total_pixels_venc);
1307
1308 writel_relaxed(de_h_begin,
1309 priv->io_base + _REG(ENCI_DE_H_BEGIN));
1310 writel_relaxed(de_h_end,
1311 priv->io_base + _REG(ENCI_DE_H_END));
1312
1313 de_v_begin_even = readl_relaxed(priv->io_base +
1314 _REG(ENCI_VFIFO2VD_LINE_TOP_START));
1315 de_v_end_even = de_v_begin_even + mode->vdisplay;
1316 de_v_begin_odd = readl_relaxed(priv->io_base +
1317 _REG(ENCI_VFIFO2VD_LINE_BOT_START));
1318 de_v_end_odd = de_v_begin_odd + mode->vdisplay;
1319
1320 writel_relaxed(de_v_begin_even,
1321 priv->io_base + _REG(ENCI_DE_V_BEGIN_EVEN));
1322 writel_relaxed(de_v_end_even,
1323 priv->io_base + _REG(ENCI_DE_V_END_EVEN));
1324 writel_relaxed(de_v_begin_odd,
1325 priv->io_base + _REG(ENCI_DE_V_BEGIN_ODD));
1326 writel_relaxed(de_v_end_odd,
1327 priv->io_base + _REG(ENCI_DE_V_END_ODD));
1328
1329 /* Program Hsync timing */
1330 hs_begin = de_h_end + front_porch_venc;
1331 if (de_h_end + front_porch_venc >= total_pixels_venc) {
1332 hs_begin -= total_pixels_venc;
1333 vs_adjust = 1;
1334 } else {
1335 hs_begin = de_h_end + front_porch_venc;
1336 vs_adjust = 0;
1337 }
1338
1339 hs_end = modulo(hs_begin + hsync_pixels_venc,
1340 total_pixels_venc);
1341 writel_relaxed(hs_begin,
1342 priv->io_base + _REG(ENCI_DVI_HSO_BEGIN));
1343 writel_relaxed(hs_end,
1344 priv->io_base + _REG(ENCI_DVI_HSO_END));
1345
1346 /* Program Vsync timing for even field */
1347 if (((de_v_end_odd - 1) + eof_lines + vs_adjust) >= lines_f1) {
1348 vs_bline_evn = (de_v_end_odd - 1)
1349 + eof_lines
1350 + vs_adjust
1351 - lines_f1;
1352 vs_eline_evn = vs_bline_evn + vsync_lines;
1353
1354 writel_relaxed(vs_bline_evn,
1355 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN));
1356
1357 writel_relaxed(vs_eline_evn,
1358 priv->io_base + _REG(ENCI_DVI_VSO_ELINE_EVN));
1359
1360 writel_relaxed(hs_begin,
1361 priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_EVN));
1362 writel_relaxed(hs_begin,
1363 priv->io_base + _REG(ENCI_DVI_VSO_END_EVN));
1364 } else {
1365 vs_bline_odd = (de_v_end_odd - 1)
1366 + eof_lines
1367 + vs_adjust;
1368
1369 writel_relaxed(vs_bline_odd,
1370 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD));
1371
1372 writel_relaxed(hs_begin,
1373 priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD));
1374
1375 if ((vs_bline_odd + vsync_lines) >= lines_f1) {
1376 vs_eline_evn = vs_bline_odd
1377 + vsync_lines
1378 - lines_f1;
1379
1380 writel_relaxed(vs_eline_evn, priv->io_base
1381 + _REG(ENCI_DVI_VSO_ELINE_EVN));
1382
1383 writel_relaxed(hs_begin, priv->io_base
1384 + _REG(ENCI_DVI_VSO_END_EVN));
1385 } else {
1386 vs_eline_odd = vs_bline_odd
1387 + vsync_lines;
1388
1389 writel_relaxed(vs_eline_odd, priv->io_base
1390 + _REG(ENCI_DVI_VSO_ELINE_ODD));
1391
1392 writel_relaxed(hs_begin, priv->io_base
1393 + _REG(ENCI_DVI_VSO_END_ODD));
1394 }
1395 }
1396
1397 /* Program Vsync timing for odd field */
1398 if (((de_v_end_even - 1) + (eof_lines + 1)) >= lines_f0) {
1399 vs_bline_odd = (de_v_end_even - 1)
1400 + (eof_lines + 1)
1401 - lines_f0;
1402 vs_eline_odd = vs_bline_odd + vsync_lines;
1403
1404 writel_relaxed(vs_bline_odd,
1405 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD));
1406
1407 writel_relaxed(vs_eline_odd,
1408 priv->io_base + _REG(ENCI_DVI_VSO_ELINE_ODD));
1409
1410 vso_begin_odd = modulo(hs_begin
1411 + (total_pixels_venc >> 1),
1412 total_pixels_venc);
1413
1414 writel_relaxed(vso_begin_odd,
1415 priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD));
1416 writel_relaxed(vso_begin_odd,
1417 priv->io_base + _REG(ENCI_DVI_VSO_END_ODD));
1418 } else {
1419 vs_bline_evn = (de_v_end_even - 1)
1420 + (eof_lines + 1);
1421
1422 writel_relaxed(vs_bline_evn,
1423 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN));
1424
1425 vso_begin_evn = modulo(hs_begin
1426 + (total_pixels_venc >> 1),
1427 total_pixels_venc);
1428
1429 writel_relaxed(vso_begin_evn, priv->io_base
1430 + _REG(ENCI_DVI_VSO_BEGIN_EVN));
1431
1432 if (vs_bline_evn + vsync_lines >= lines_f0) {
1433 vs_eline_odd = vs_bline_evn
1434 + vsync_lines
1435 - lines_f0;
1436
1437 writel_relaxed(vs_eline_odd, priv->io_base
1438 + _REG(ENCI_DVI_VSO_ELINE_ODD));
1439
1440 writel_relaxed(vso_begin_evn, priv->io_base
1441 + _REG(ENCI_DVI_VSO_END_ODD));
1442 } else {
1443 vs_eline_evn = vs_bline_evn + vsync_lines;
1444
1445 writel_relaxed(vs_eline_evn, priv->io_base
1446 + _REG(ENCI_DVI_VSO_ELINE_EVN));
1447
1448 writel_relaxed(vso_begin_evn, priv->io_base
1449 + _REG(ENCI_DVI_VSO_END_EVN));
1450 }
1451 }
1452 } else {
1453 writel_relaxed(vmode->encp.dvi_settings,
1454 priv->io_base + _REG(VENC_DVI_SETTING));
1455 writel_relaxed(vmode->encp.video_mode,
1456 priv->io_base + _REG(ENCP_VIDEO_MODE));
1457 writel_relaxed(vmode->encp.video_mode_adv,
1458 priv->io_base + _REG(ENCP_VIDEO_MODE_ADV));
1459 if (vmode->encp.video_prog_mode_present)
1460 writel_relaxed(vmode->encp.video_prog_mode,
1461 priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
1462 if (vmode->encp.video_sync_mode_present)
1463 writel_relaxed(vmode->encp.video_sync_mode,
1464 priv->io_base + _REG(ENCP_VIDEO_SYNC_MODE));
1465 if (vmode->encp.video_yc_dly_present)
1466 writel_relaxed(vmode->encp.video_yc_dly,
1467 priv->io_base + _REG(ENCP_VIDEO_YC_DLY));
1468 if (vmode->encp.video_rgb_ctrl_present)
1469 writel_relaxed(vmode->encp.video_rgb_ctrl,
1470 priv->io_base + _REG(ENCP_VIDEO_RGB_CTRL));
1471 if (vmode->encp.video_filt_ctrl_present)
1472 writel_relaxed(vmode->encp.video_filt_ctrl,
1473 priv->io_base + _REG(ENCP_VIDEO_FILT_CTRL));
1474 if (vmode->encp.video_ofld_voav_ofst_present)
1475 writel_relaxed(vmode->encp.video_ofld_voav_ofst,
1476 priv->io_base
1477 + _REG(ENCP_VIDEO_OFLD_VOAV_OFST));
1478 writel_relaxed(vmode->encp.yfp1_htime,
1479 priv->io_base + _REG(ENCP_VIDEO_YFP1_HTIME));
1480 writel_relaxed(vmode->encp.yfp2_htime,
1481 priv->io_base + _REG(ENCP_VIDEO_YFP2_HTIME));
1482 writel_relaxed(vmode->encp.max_pxcnt,
1483 priv->io_base + _REG(ENCP_VIDEO_MAX_PXCNT));
1484 writel_relaxed(vmode->encp.hspuls_begin,
1485 priv->io_base + _REG(ENCP_VIDEO_HSPULS_BEGIN));
1486 writel_relaxed(vmode->encp.hspuls_end,
1487 priv->io_base + _REG(ENCP_VIDEO_HSPULS_END));
1488 writel_relaxed(vmode->encp.hspuls_switch,
1489 priv->io_base + _REG(ENCP_VIDEO_HSPULS_SWITCH));
1490 writel_relaxed(vmode->encp.vspuls_begin,
1491 priv->io_base + _REG(ENCP_VIDEO_VSPULS_BEGIN));
1492 writel_relaxed(vmode->encp.vspuls_end,
1493 priv->io_base + _REG(ENCP_VIDEO_VSPULS_END));
1494 writel_relaxed(vmode->encp.vspuls_bline,
1495 priv->io_base + _REG(ENCP_VIDEO_VSPULS_BLINE));
1496 writel_relaxed(vmode->encp.vspuls_eline,
1497 priv->io_base + _REG(ENCP_VIDEO_VSPULS_ELINE));
1498 if (vmode->encp.eqpuls_begin_present)
1499 writel_relaxed(vmode->encp.eqpuls_begin,
1500 priv->io_base + _REG(ENCP_VIDEO_EQPULS_BEGIN));
1501 if (vmode->encp.eqpuls_end_present)
1502 writel_relaxed(vmode->encp.eqpuls_end,
1503 priv->io_base + _REG(ENCP_VIDEO_EQPULS_END));
1504 if (vmode->encp.eqpuls_bline_present)
1505 writel_relaxed(vmode->encp.eqpuls_bline,
1506 priv->io_base + _REG(ENCP_VIDEO_EQPULS_BLINE));
1507 if (vmode->encp.eqpuls_eline_present)
1508 writel_relaxed(vmode->encp.eqpuls_eline,
1509 priv->io_base + _REG(ENCP_VIDEO_EQPULS_ELINE));
1510 writel_relaxed(vmode->encp.havon_begin,
1511 priv->io_base + _REG(ENCP_VIDEO_HAVON_BEGIN));
1512 writel_relaxed(vmode->encp.havon_end,
1513 priv->io_base + _REG(ENCP_VIDEO_HAVON_END));
1514 writel_relaxed(vmode->encp.vavon_bline,
1515 priv->io_base + _REG(ENCP_VIDEO_VAVON_BLINE));
1516 writel_relaxed(vmode->encp.vavon_eline,
1517 priv->io_base + _REG(ENCP_VIDEO_VAVON_ELINE));
1518 writel_relaxed(vmode->encp.hso_begin,
1519 priv->io_base + _REG(ENCP_VIDEO_HSO_BEGIN));
1520 writel_relaxed(vmode->encp.hso_end,
1521 priv->io_base + _REG(ENCP_VIDEO_HSO_END));
1522 writel_relaxed(vmode->encp.vso_begin,
1523 priv->io_base + _REG(ENCP_VIDEO_VSO_BEGIN));
1524 writel_relaxed(vmode->encp.vso_end,
1525 priv->io_base + _REG(ENCP_VIDEO_VSO_END));
1526 writel_relaxed(vmode->encp.vso_bline,
1527 priv->io_base + _REG(ENCP_VIDEO_VSO_BLINE));
1528 if (vmode->encp.vso_eline_present)
1529 writel_relaxed(vmode->encp.vso_eline,
1530 priv->io_base + _REG(ENCP_VIDEO_VSO_ELINE));
1531 if (vmode->encp.sy_val_present)
1532 writel_relaxed(vmode->encp.sy_val,
1533 priv->io_base + _REG(ENCP_VIDEO_SY_VAL));
1534 if (vmode->encp.sy2_val_present)
1535 writel_relaxed(vmode->encp.sy2_val,
1536 priv->io_base + _REG(ENCP_VIDEO_SY2_VAL));
1537 writel_relaxed(vmode->encp.max_lncnt,
1538 priv->io_base + _REG(ENCP_VIDEO_MAX_LNCNT));
1539
1540 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN));
1541
1542 /* Set DE signal’s polarity is active high */
1543 writel_bits_relaxed(BIT(14), BIT(14),
1544 priv->io_base + _REG(ENCP_VIDEO_MODE));
1545
1546 /* Program DE timing */
1547 de_h_begin = modulo(readl_relaxed(priv->io_base +
1548 _REG(ENCP_VIDEO_HAVON_BEGIN))
1549 + venc_hdmi_latency,
1550 total_pixels_venc);
1551 de_h_end = modulo(de_h_begin + active_pixels_venc,
1552 total_pixels_venc);
1553
1554 writel_relaxed(de_h_begin,
1555 priv->io_base + _REG(ENCP_DE_H_BEGIN));
1556 writel_relaxed(de_h_end,
1557 priv->io_base + _REG(ENCP_DE_H_END));
1558
1559 /* Program DE timing for even field */
1560 de_v_begin_even = readl_relaxed(priv->io_base
1561 + _REG(ENCP_VIDEO_VAVON_BLINE));
1562 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1563 de_v_end_even = de_v_begin_even +
1564 (mode->vdisplay / 2);
1565 else
1566 de_v_end_even = de_v_begin_even + mode->vdisplay;
1567
1568 writel_relaxed(de_v_begin_even,
1569 priv->io_base + _REG(ENCP_DE_V_BEGIN_EVEN));
1570 writel_relaxed(de_v_end_even,
1571 priv->io_base + _REG(ENCP_DE_V_END_EVEN));
1572
1573 /* Program DE timing for odd field if needed */
1574 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1575 unsigned int ofld_voav_ofst =
1576 readl_relaxed(priv->io_base +
1577 _REG(ENCP_VIDEO_OFLD_VOAV_OFST));
1578 de_v_begin_odd = to_signed((ofld_voav_ofst & 0xf0) >> 4)
1579 + de_v_begin_even
1580 + ((mode->vtotal - 1) / 2);
1581 de_v_end_odd = de_v_begin_odd + (mode->vdisplay / 2);
1582
1583 writel_relaxed(de_v_begin_odd,
1584 priv->io_base + _REG(ENCP_DE_V_BEGIN_ODD));
1585 writel_relaxed(de_v_end_odd,
1586 priv->io_base + _REG(ENCP_DE_V_END_ODD));
1587 }
1588
1589 /* Program Hsync timing */
1590 if ((de_h_end + front_porch_venc) >= total_pixels_venc) {
1591 hs_begin = de_h_end
1592 + front_porch_venc
1593 - total_pixels_venc;
1594 vs_adjust = 1;
1595 } else {
1596 hs_begin = de_h_end
1597 + front_porch_venc;
1598 vs_adjust = 0;
1599 }
1600
1601 hs_end = modulo(hs_begin + hsync_pixels_venc,
1602 total_pixels_venc);
1603
1604 writel_relaxed(hs_begin,
1605 priv->io_base + _REG(ENCP_DVI_HSO_BEGIN));
1606 writel_relaxed(hs_end,
1607 priv->io_base + _REG(ENCP_DVI_HSO_END));
1608
1609 /* Program Vsync timing for even field */
1610 if (de_v_begin_even >=
1611 (sof_lines + vsync_lines + (1 - vs_adjust)))
1612 vs_bline_evn = de_v_begin_even
1613 - sof_lines
1614 - vsync_lines
1615 - (1 - vs_adjust);
1616 else
1617 vs_bline_evn = mode->vtotal
1618 + de_v_begin_even
1619 - sof_lines
1620 - vsync_lines
1621 - (1 - vs_adjust);
1622
1623 vs_eline_evn = modulo(vs_bline_evn + vsync_lines,
1624 mode->vtotal);
1625
1626 writel_relaxed(vs_bline_evn,
1627 priv->io_base + _REG(ENCP_DVI_VSO_BLINE_EVN));
1628 writel_relaxed(vs_eline_evn,
1629 priv->io_base + _REG(ENCP_DVI_VSO_ELINE_EVN));
1630
1631 vso_begin_evn = hs_begin;
1632 writel_relaxed(vso_begin_evn,
1633 priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_EVN));
1634 writel_relaxed(vso_begin_evn,
1635 priv->io_base + _REG(ENCP_DVI_VSO_END_EVN));
1636
1637 /* Program Vsync timing for odd field if needed */
1638 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1639 vs_bline_odd = (de_v_begin_odd - 1)
1640 - sof_lines
1641 - vsync_lines;
1642 vs_eline_odd = (de_v_begin_odd - 1)
1643 - vsync_lines;
1644 vso_begin_odd = modulo(hs_begin
1645 + (total_pixels_venc >> 1),
1646 total_pixels_venc);
1647
1648 writel_relaxed(vs_bline_odd,
1649 priv->io_base + _REG(ENCP_DVI_VSO_BLINE_ODD));
1650 writel_relaxed(vs_eline_odd,
1651 priv->io_base + _REG(ENCP_DVI_VSO_ELINE_ODD));
1652 writel_relaxed(vso_begin_odd,
1653 priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_ODD));
1654 writel_relaxed(vso_begin_odd,
1655 priv->io_base + _REG(ENCP_DVI_VSO_END_ODD));
1656 }
1657
1658 /* Select ENCP for VIU */
1659 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCP);
1660 }
1661
1662 writel_relaxed((use_enci ? 1 : 2) |
1663 (mode->flags & DRM_MODE_FLAG_PHSYNC ? 1 << 2 : 0) |
1664 (mode->flags & DRM_MODE_FLAG_PVSYNC ? 1 << 3 : 0) |
1665 4 << 5 |
1666 (venc_repeat ? 1 << 8 : 0) |
1667 (hdmi_repeat ? 1 << 12 : 0),
1668 priv->io_base + _REG(VPU_HDMI_SETTING));
1669
1670 priv->venc.hdmi_repeat = hdmi_repeat;
1671 priv->venc.venc_repeat = venc_repeat;
1672 priv->venc.hdmi_use_enci = use_enci;
1673
1674 priv->venc.current_mode = MESON_VENC_MODE_HDMI;
1675}
1676EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set);
1677
1678void meson_venci_cvbs_mode_set(struct meson_drm *priv,
1679 struct meson_cvbs_enci_mode *mode)
1680{
1681 if (mode->mode_tag == priv->venc.current_mode)
1682 return;
1683
1684 /* CVBS Filter settings */
1685 writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL));
1686 writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2));
1687
1688 /* Digital Video Select : Interlace, clk27 clk, external */
1689 writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING));
1690
1691 /* Reset Video Mode */
1692 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE));
1693 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
1694
1695 /* Horizontal sync signal output */
1696 writel_relaxed(mode->hso_begin,
1697 priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN));
1698 writel_relaxed(mode->hso_end,
1699 priv->io_base + _REG(ENCI_SYNC_HSO_END));
1700
1701 /* Vertical Sync lines */
1702 writel_relaxed(mode->vso_even,
1703 priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN));
1704 writel_relaxed(mode->vso_odd,
1705 priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));
1706
1707 /* Macrovision max amplitude change */
1708 writel_relaxed(0x8100 + mode->macv_max_amp,
1709 priv->io_base + _REG(ENCI_MACV_MAX_AMP));
1710
1711 /* Video mode */
1712 writel_relaxed(mode->video_prog_mode,
1713 priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
1714 writel_relaxed(mode->video_mode,
1715 priv->io_base + _REG(ENCI_VIDEO_MODE));
1716
1717 /* Advanced Video Mode :
1718 * Demux shifting 0x2
1719 * Blank line end at line17/22
1720 * High bandwidth Luma Filter
1721 * Low bandwidth Chroma Filter
1722 * Bypass luma low pass filter
1723 * No macrovision on CSYNC
1724 */
1725 writel_relaxed(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
1726
1727 writel(mode->sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH));
1728
1729 /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
1730 writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE));
1731
1732 /* 0x3 Y, C, and Component Y delay */
1733 writel_relaxed(mode->yc_delay, priv->io_base + _REG(ENCI_YC_DELAY));
1734
1735 /* Timings */
1736 writel_relaxed(mode->pixel_start,
1737 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START));
1738 writel_relaxed(mode->pixel_end,
1739 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END));
1740
1741 writel_relaxed(mode->top_field_line_start,
1742 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START));
1743 writel_relaxed(mode->top_field_line_end,
1744 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END));
1745
1746 writel_relaxed(mode->bottom_field_line_start,
1747 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START));
1748 writel_relaxed(mode->bottom_field_line_end,
1749 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END));
1750
1751 /* Internal Venc, Internal VIU Sync, Internal Vencoder */
1752 writel_relaxed(0, priv->io_base + _REG(VENC_SYNC_ROUTE));
1753
1754 /* UNreset Interlaced TV Encoder */
1755 writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST));
1756
1757 /* Enable Vfifo2vd, Y_Cb_Y_Cr select */
1758 writel_relaxed(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
1759
1760 /* Power UP Dacs */
1761 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_SETTING));
1762
1763 /* Video Upsampling */
1764 writel_relaxed(0x0061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL0));
1765 writel_relaxed(0x4061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL1));
1766 writel_relaxed(0x5061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL2));
1767
1768 /* Select Interlace Y DACs */
1769 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL0));
1770 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL1));
1771 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL2));
1772 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL3));
1773 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL4));
1774 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL5));
1775
1776 /* Select ENCI for VIU */
1777 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);
1778
1779 /* Enable ENCI FIFO */
1780 writel_relaxed(0x2000, priv->io_base + _REG(VENC_VDAC_FIFO_CTRL));
1781
1782 /* Select ENCI DACs 0, 1, 4, and 5 */
1783 writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_0));
1784 writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_1));
1785
1786 /* Interlace video enable */
1787 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN));
1788
1789 /* Configure Video Saturation / Contrast / Brightness / Hue */
1790 writel_relaxed(mode->video_saturation,
1791 priv->io_base + _REG(ENCI_VIDEO_SAT));
1792 writel_relaxed(mode->video_contrast,
1793 priv->io_base + _REG(ENCI_VIDEO_CONT));
1794 writel_relaxed(mode->video_brightness,
1795 priv->io_base + _REG(ENCI_VIDEO_BRIGHT));
1796 writel_relaxed(mode->video_hue,
1797 priv->io_base + _REG(ENCI_VIDEO_HUE));
1798
1799 /* Enable DAC0 Filter */
1800 writel_relaxed(0x1, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0));
1801 writel_relaxed(0xfc48, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL1));
1802
1803 /* 0 in Macrovision register 0 */
1804 writel_relaxed(0, priv->io_base + _REG(ENCI_MACV_N0));
1805
1806 /* Analog Synchronization and color burst value adjust */
1807 writel_relaxed(mode->analog_sync_adj,
1808 priv->io_base + _REG(ENCI_SYNC_ADJ));
1809
1810 priv->venc.current_mode = mode->mode_tag;
1811}
1812
1813/* Returns the current ENCI field polarity */
1814unsigned int meson_venci_get_field(struct meson_drm *priv)
1815{
1816 return readl_relaxed(priv->io_base + _REG(ENCI_INFO_READ)) & BIT(29);
1817}
1818
1819void meson_venc_enable_vsync(struct meson_drm *priv)
1820{
1821 writel_relaxed(2, priv->io_base + _REG(VENC_INTCTRL));
1822}
1823
1824void meson_venc_disable_vsync(struct meson_drm *priv)
1825{
1826 writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL));
1827}
1828
1829void meson_venc_init(struct meson_drm *priv)
1830{
1831 /* Disable CVBS VDAC */
1832 regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0);
1833 regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8);
1834
1835 /* Power Down Dacs */
1836 writel_relaxed(0xff, priv->io_base + _REG(VENC_VDAC_SETTING));
1837
1838 /* Disable HDMI PHY */
1839 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
1840
1841 /* Disable HDMI */
1842 writel_bits_relaxed(0x3, 0,
1843 priv->io_base + _REG(VPU_HDMI_SETTING));
1844
1845 /* Disable all encoders */
1846 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
1847 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
1848 writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
1849
1850 /* Disable VSync IRQ */
1851 meson_venc_disable_vsync(priv);
1852
1853 priv->venc.current_mode = MESON_VENC_MODE_NONE;
1854}