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