2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
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.
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.
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/>.
20 #include <linux/kernel.h>
21 #include <linux/module.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"
32 * VENC Handle the pixels encoding to the output formats.
33 * We handle the following encodings :
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
41 * - LCD Panel encoding via ENCL
42 * - TV Panel encoding via ENCT
48 * _____ _____ ____________________
49 * vd1---| |-| | | VENC /---------|----VDAC
50 * vd2---| VIU |-| VPP |-|-----ENCI/-ENCI_DVI-|-|
51 * osd1--| |-| | | \ | X--HDMI-TX
52 * osd2--|_____|-|_____| | |\-ENCP--ENCP_DVI-|-|
54 * | \--ENCL-----------|----LVDS
55 * |____________________|
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.
65 * The ENCI and ENCP encoders needs specially defined parameters for each
66 * supported mode and thus cannot be determined from standard video timings.
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.
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 */
78 struct meson_cvbs_enci_mode meson_cvbs_enci_pal
= {
79 .mode_tag
= MESON_VENC_MODE_CVBS_PAL
,
85 .video_prog_mode
= 0xff,
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,
97 .video_brightness
= 0,
99 .analog_sync_adj
= 0x8080,
102 struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc
= {
103 .mode_tag
= MESON_VENC_MODE_CVBS_NTSC
,
109 .video_prog_mode
= 0xf0,
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,
121 .video_brightness
= 0,
123 .analog_sync_adj
= 0x9c00,
126 union meson_hdmi_venc_mode
{
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
;
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
;
192 unsigned int sy2_val
;
193 bool sy2_val_present
;
194 unsigned int max_lncnt
;
198 union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i
= {
204 .macv_max_amp
= 0x810b,
205 .video_prog_mode
= 0xf0,
211 .top_field_line_start
= 18,
212 .top_field_line_end
= 258,
213 .bottom_field_line_start
= 19,
214 .bottom_field_line_end
= 259,
218 union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i
= {
224 .macv_max_amp
= 8107,
225 .video_prog_mode
= 0xff,
231 .top_field_line_start
= 22,
232 .top_field_line_end
= 310,
233 .bottom_field_line_start
= 23,
234 .bottom_field_line_end
= 311,
238 union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p
= {
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,
249 .video_filt_ctrl
= 0x2052,
250 .video_filt_ctrl_present
= true,
251 /* video_ofld_voav_ofst */
255 .hspuls_begin
= 0x22,
277 .sy_val_present
= true,
279 .sy2_val_present
= true,
284 union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p
= {
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,
295 .video_filt_ctrl
= 0x52,
296 .video_filt_ctrl_present
= true,
297 /* video_ofld_voav_ofst */
323 .sy_val_present
= true,
325 .sy2_val_present
= true,
330 union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60
= {
332 .dvi_settings
= 0x2029,
333 .video_mode
= 0x4040,
334 .video_mode_adv
= 0x19,
335 /* video_prog_mode */
336 /* video_sync_mode */
339 /* video_filt_ctrl */
340 /* video_ofld_voav_ofst */
365 .vso_eline_present
= true,
372 union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50
= {
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,
382 .video_yc_dly_present
= true,
384 /* video_filt_ctrl */
385 /* video_ofld_voav_ofst */
410 .vso_eline_present
= true,
417 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60
= {
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,
428 /* video_filt_ctrl */
429 .video_ofld_voav_ofst
= 0x11,
430 .video_ofld_voav_ofst_present
= true,
445 .eqpuls_begin
= 2288,
446 .eqpuls_begin_present
= true,
448 .eqpuls_end_present
= true,
450 .eqpuls_bline_present
= true,
452 .eqpuls_eline_present
= true,
459 .vso_eline_present
= true,
466 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50
= {
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,
477 /* video_filt_ctrl */
478 .video_ofld_voav_ofst
= 0x11,
479 .video_ofld_voav_ofst_present
= true,
494 .eqpuls_begin
= 2288,
495 .eqpuls_begin_present
= true,
497 .eqpuls_end_present
= true,
499 .eqpuls_bline_present
= true,
501 .eqpuls_eline_present
= true,
508 .vso_eline_present
= true,
515 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24
= {
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,
525 .video_yc_dly_present
= true,
527 .video_rgb_ctrl_present
= true,
528 .video_filt_ctrl
= 0x1052,
529 .video_filt_ctrl_present
= true,
530 /* video_ofld_voav_ofst */
548 .eqpuls_bline_present
= true,
550 .eqpuls_eline_present
= true,
557 .vso_eline_present
= true,
564 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30
= {
567 .video_mode
= 0x4040,
568 .video_mode_adv
= 0x18,
569 .video_prog_mode
= 0x100,
570 .video_prog_mode_present
= true,
571 /* video_sync_mode */
574 .video_filt_ctrl
= 0x1052,
575 .video_filt_ctrl_present
= true,
576 /* video_ofld_voav_ofst */
580 .hspuls_begin
= 2156,
601 .vso_eline_present
= true,
608 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50
= {
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,
618 .video_yc_dly_present
= true,
620 .video_rgb_ctrl_present
= true,
621 /* video_filt_ctrl */
622 /* video_ofld_voav_ofst */
640 .eqpuls_bline_present
= true,
642 .eqpuls_eline_present
= true,
649 .vso_eline_present
= true,
656 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60
= {
659 .video_mode
= 0x4040,
660 .video_mode_adv
= 0x18,
661 .video_prog_mode
= 0x100,
662 .video_prog_mode_present
= true,
663 /* video_sync_mode */
666 .video_filt_ctrl
= 0x1052,
667 .video_filt_ctrl_present
= true,
668 /* video_ofld_voav_ofst */
672 .hspuls_begin
= 2156,
693 .vso_eline_present
= true,
700 struct meson_hdmi_venc_vic_mode
{
702 union meson_hdmi_venc_mode
*mode
;
703 } meson_hdmi_venc_vic_modes
[] = {
704 { 6, &meson_hdmi_enci_mode_480i
},
705 { 7, &meson_hdmi_enci_mode_480i
},
706 { 21, &meson_hdmi_enci_mode_576i
},
707 { 22, &meson_hdmi_enci_mode_576i
},
708 { 2, &meson_hdmi_encp_mode_480p
},
709 { 3, &meson_hdmi_encp_mode_480p
},
710 { 17, &meson_hdmi_encp_mode_576p
},
711 { 18, &meson_hdmi_encp_mode_576p
},
712 { 4, &meson_hdmi_encp_mode_720p60
},
713 { 19, &meson_hdmi_encp_mode_720p50
},
714 { 5, &meson_hdmi_encp_mode_1080i60
},
715 { 20, &meson_hdmi_encp_mode_1080i50
},
716 { 32, &meson_hdmi_encp_mode_1080p24
},
717 { 34, &meson_hdmi_encp_mode_1080p30
},
718 { 31, &meson_hdmi_encp_mode_1080p50
},
719 { 16, &meson_hdmi_encp_mode_1080p60
},
720 { 0, NULL
}, /* sentinel */
723 static signed int to_signed(unsigned int a
)
731 static unsigned long modulo(unsigned long a
, unsigned long b
)
739 bool meson_venc_hdmi_supported_vic(int vic
)
741 struct meson_hdmi_venc_vic_mode
*vmode
= meson_hdmi_venc_vic_modes
;
743 while (vmode
->vic
&& vmode
->mode
) {
744 if (vmode
->vic
== vic
)
751 EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic
);
753 static union meson_hdmi_venc_mode
*meson_venc_hdmi_get_vic_vmode(int vic
)
755 struct meson_hdmi_venc_vic_mode
*vmode
= meson_hdmi_venc_vic_modes
;
757 while (vmode
->vic
&& vmode
->mode
) {
758 if (vmode
->vic
== vic
)
766 bool meson_venc_hdmi_venc_repeat(int vic
)
768 /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
769 if (vic
== 6 || vic
== 7 || /* 480i */
770 vic
== 21 || vic
== 22 || /* 576i */
771 vic
== 17 || vic
== 18 || /* 576p */
772 vic
== 2 || vic
== 3 || /* 480p */
773 vic
== 4 || /* 720p60 */
774 vic
== 19 || /* 720p50 */
775 vic
== 5 || /* 1080i60 */
776 vic
== 20) /* 1080i50 */
781 EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat
);
783 void meson_venc_hdmi_mode_set(struct meson_drm
*priv
, int vic
,
784 struct drm_display_mode
*mode
)
786 union meson_hdmi_venc_mode
*vmode
= NULL
;
787 bool use_enci
= false;
788 bool venc_repeat
= false;
789 bool hdmi_repeat
= false;
790 unsigned int venc_hdmi_latency
= 2;
791 unsigned long total_pixels_venc
= 0;
792 unsigned long active_pixels_venc
= 0;
793 unsigned long front_porch_venc
= 0;
794 unsigned long hsync_pixels_venc
= 0;
795 unsigned long de_h_begin
= 0;
796 unsigned long de_h_end
= 0;
797 unsigned long de_v_begin_even
= 0;
798 unsigned long de_v_end_even
= 0;
799 unsigned long de_v_begin_odd
= 0;
800 unsigned long de_v_end_odd
= 0;
801 unsigned long hs_begin
= 0;
802 unsigned long hs_end
= 0;
803 unsigned long vs_adjust
= 0;
804 unsigned long vs_bline_evn
= 0;
805 unsigned long vs_eline_evn
= 0;
806 unsigned long vs_bline_odd
= 0;
807 unsigned long vs_eline_odd
= 0;
808 unsigned long vso_begin_evn
= 0;
809 unsigned long vso_begin_odd
= 0;
810 unsigned int eof_lines
;
811 unsigned int sof_lines
;
812 unsigned int vsync_lines
;
814 vmode
= meson_venc_hdmi_get_vic_vmode(vic
);
816 dev_err(priv
->dev
, "%s: Fatal Error, unsupported vic %d\n",
821 /* Use VENCI for 480i and 576i and double HDMI pixels */
822 if (mode
->flags
& DRM_MODE_FLAG_DBLCLK
) {
825 venc_hdmi_latency
= 1;
828 /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
829 if (meson_venc_hdmi_venc_repeat(vic
))
832 eof_lines
= mode
->vsync_start
- mode
->vdisplay
;
833 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
835 sof_lines
= mode
->vtotal
- mode
->vsync_end
;
836 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
838 vsync_lines
= mode
->vsync_end
- mode
->vsync_start
;
839 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
842 total_pixels_venc
= mode
->htotal
;
844 total_pixels_venc
/= 2;
846 total_pixels_venc
*= 2;
848 active_pixels_venc
= mode
->hdisplay
;
850 active_pixels_venc
/= 2;
852 active_pixels_venc
*= 2;
854 front_porch_venc
= (mode
->hsync_start
- mode
->hdisplay
);
856 front_porch_venc
/= 2;
858 front_porch_venc
*= 2;
860 hsync_pixels_venc
= (mode
->hsync_end
- mode
->hsync_start
);
862 hsync_pixels_venc
/= 2;
864 hsync_pixels_venc
*= 2;
867 writel_bits_relaxed(0x1f, 0x1f,
868 priv
->io_base
+ _REG(VENC_VDAC_SETTING
));
870 writel_relaxed(0, priv
->io_base
+ _REG(ENCI_VIDEO_EN
));
871 writel_relaxed(0, priv
->io_base
+ _REG(ENCP_VIDEO_EN
));
874 unsigned int lines_f0
;
875 unsigned int lines_f1
;
877 /* CVBS Filter settings */
878 writel_relaxed(0x12, priv
->io_base
+ _REG(ENCI_CFILT_CTRL
));
879 writel_relaxed(0x12, priv
->io_base
+ _REG(ENCI_CFILT_CTRL2
));
881 /* Digital Video Select : Interlace, clk27 clk, external */
882 writel_relaxed(0, priv
->io_base
+ _REG(VENC_DVI_SETTING
));
884 /* Reset Video Mode */
885 writel_relaxed(0, priv
->io_base
+ _REG(ENCI_VIDEO_MODE
));
886 writel_relaxed(0, priv
->io_base
+ _REG(ENCI_VIDEO_MODE_ADV
));
888 /* Horizontal sync signal output */
889 writel_relaxed(vmode
->enci
.hso_begin
,
890 priv
->io_base
+ _REG(ENCI_SYNC_HSO_BEGIN
));
891 writel_relaxed(vmode
->enci
.hso_end
,
892 priv
->io_base
+ _REG(ENCI_SYNC_HSO_END
));
894 /* Vertical Sync lines */
895 writel_relaxed(vmode
->enci
.vso_even
,
896 priv
->io_base
+ _REG(ENCI_SYNC_VSO_EVNLN
));
897 writel_relaxed(vmode
->enci
.vso_odd
,
898 priv
->io_base
+ _REG(ENCI_SYNC_VSO_ODDLN
));
900 /* Macrovision max amplitude change */
901 writel_relaxed(vmode
->enci
.macv_max_amp
,
902 priv
->io_base
+ _REG(ENCI_MACV_MAX_AMP
));
905 writel_relaxed(vmode
->enci
.video_prog_mode
,
906 priv
->io_base
+ _REG(VENC_VIDEO_PROG_MODE
));
907 writel_relaxed(vmode
->enci
.video_mode
,
908 priv
->io_base
+ _REG(ENCI_VIDEO_MODE
));
910 /* Advanced Video Mode :
912 * Blank line end at line17/22
913 * High bandwidth Luma Filter
914 * Low bandwidth Chroma Filter
915 * Bypass luma low pass filter
916 * No macrovision on CSYNC
918 writel_relaxed(0x26, priv
->io_base
+ _REG(ENCI_VIDEO_MODE_ADV
));
920 writel(vmode
->enci
.sch_adjust
,
921 priv
->io_base
+ _REG(ENCI_VIDEO_SCH
));
923 /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
924 writel_relaxed(0x07, priv
->io_base
+ _REG(ENCI_SYNC_MODE
));
926 if (vmode
->enci
.yc_delay
)
927 writel_relaxed(vmode
->enci
.yc_delay
,
928 priv
->io_base
+ _REG(ENCI_YC_DELAY
));
931 /* UNreset Interlaced TV Encoder */
932 writel_relaxed(0, priv
->io_base
+ _REG(ENCI_DBG_PX_RST
));
934 /* Enable Vfifo2vd, Y_Cb_Y_Cr select */
935 writel_relaxed(0x4e01, priv
->io_base
+ _REG(ENCI_VFIFO2VD_CTL
));
938 writel_relaxed(vmode
->enci
.pixel_start
,
939 priv
->io_base
+ _REG(ENCI_VFIFO2VD_PIXEL_START
));
940 writel_relaxed(vmode
->enci
.pixel_end
,
941 priv
->io_base
+ _REG(ENCI_VFIFO2VD_PIXEL_END
));
943 writel_relaxed(vmode
->enci
.top_field_line_start
,
944 priv
->io_base
+ _REG(ENCI_VFIFO2VD_LINE_TOP_START
));
945 writel_relaxed(vmode
->enci
.top_field_line_end
,
946 priv
->io_base
+ _REG(ENCI_VFIFO2VD_LINE_TOP_END
));
948 writel_relaxed(vmode
->enci
.bottom_field_line_start
,
949 priv
->io_base
+ _REG(ENCI_VFIFO2VD_LINE_BOT_START
));
950 writel_relaxed(vmode
->enci
.bottom_field_line_end
,
951 priv
->io_base
+ _REG(ENCI_VFIFO2VD_LINE_BOT_END
));
953 /* Select ENCI for VIU */
954 meson_vpp_setup_mux(priv
, MESON_VIU_VPP_MUX_ENCI
);
956 /* Interlace video enable */
957 writel_relaxed(1, priv
->io_base
+ _REG(ENCI_VIDEO_EN
));
959 lines_f0
= mode
->vtotal
>> 1;
960 lines_f1
= lines_f0
+ 1;
962 de_h_begin
= modulo(readl_relaxed(priv
->io_base
+
963 _REG(ENCI_VFIFO2VD_PIXEL_START
))
966 de_h_end
= modulo(de_h_begin
+ active_pixels_venc
,
969 writel_relaxed(de_h_begin
,
970 priv
->io_base
+ _REG(ENCI_DE_H_BEGIN
));
971 writel_relaxed(de_h_end
,
972 priv
->io_base
+ _REG(ENCI_DE_H_END
));
974 de_v_begin_even
= readl_relaxed(priv
->io_base
+
975 _REG(ENCI_VFIFO2VD_LINE_TOP_START
));
976 de_v_end_even
= de_v_begin_even
+ mode
->vdisplay
;
977 de_v_begin_odd
= readl_relaxed(priv
->io_base
+
978 _REG(ENCI_VFIFO2VD_LINE_BOT_START
));
979 de_v_end_odd
= de_v_begin_odd
+ mode
->vdisplay
;
981 writel_relaxed(de_v_begin_even
,
982 priv
->io_base
+ _REG(ENCI_DE_V_BEGIN_EVEN
));
983 writel_relaxed(de_v_end_even
,
984 priv
->io_base
+ _REG(ENCI_DE_V_END_EVEN
));
985 writel_relaxed(de_v_begin_odd
,
986 priv
->io_base
+ _REG(ENCI_DE_V_BEGIN_ODD
));
987 writel_relaxed(de_v_end_odd
,
988 priv
->io_base
+ _REG(ENCI_DE_V_END_ODD
));
990 /* Program Hsync timing */
991 hs_begin
= de_h_end
+ front_porch_venc
;
992 if (de_h_end
+ front_porch_venc
>= total_pixels_venc
) {
993 hs_begin
-= total_pixels_venc
;
996 hs_begin
= de_h_end
+ front_porch_venc
;
1000 hs_end
= modulo(hs_begin
+ hsync_pixels_venc
,
1002 writel_relaxed(hs_begin
,
1003 priv
->io_base
+ _REG(ENCI_DVI_HSO_BEGIN
));
1004 writel_relaxed(hs_end
,
1005 priv
->io_base
+ _REG(ENCI_DVI_HSO_END
));
1007 /* Program Vsync timing for even field */
1008 if (((de_v_end_odd
- 1) + eof_lines
+ vs_adjust
) >= lines_f1
) {
1009 vs_bline_evn
= (de_v_end_odd
- 1)
1013 vs_eline_evn
= vs_bline_evn
+ vsync_lines
;
1015 writel_relaxed(vs_bline_evn
,
1016 priv
->io_base
+ _REG(ENCI_DVI_VSO_BLINE_EVN
));
1018 writel_relaxed(vs_eline_evn
,
1019 priv
->io_base
+ _REG(ENCI_DVI_VSO_ELINE_EVN
));
1021 writel_relaxed(hs_begin
,
1022 priv
->io_base
+ _REG(ENCI_DVI_VSO_BEGIN_EVN
));
1023 writel_relaxed(hs_begin
,
1024 priv
->io_base
+ _REG(ENCI_DVI_VSO_END_EVN
));
1026 vs_bline_odd
= (de_v_end_odd
- 1)
1030 writel_relaxed(vs_bline_odd
,
1031 priv
->io_base
+ _REG(ENCI_DVI_VSO_BLINE_ODD
));
1033 writel_relaxed(hs_begin
,
1034 priv
->io_base
+ _REG(ENCI_DVI_VSO_BEGIN_ODD
));
1036 if ((vs_bline_odd
+ vsync_lines
) >= lines_f1
) {
1037 vs_eline_evn
= vs_bline_odd
1041 writel_relaxed(vs_eline_evn
, priv
->io_base
1042 + _REG(ENCI_DVI_VSO_ELINE_EVN
));
1044 writel_relaxed(hs_begin
, priv
->io_base
1045 + _REG(ENCI_DVI_VSO_END_EVN
));
1047 vs_eline_odd
= vs_bline_odd
1050 writel_relaxed(vs_eline_odd
, priv
->io_base
1051 + _REG(ENCI_DVI_VSO_ELINE_ODD
));
1053 writel_relaxed(hs_begin
, priv
->io_base
1054 + _REG(ENCI_DVI_VSO_END_ODD
));
1058 /* Program Vsync timing for odd field */
1059 if (((de_v_end_even
- 1) + (eof_lines
+ 1)) >= lines_f0
) {
1060 vs_bline_odd
= (de_v_end_even
- 1)
1063 vs_eline_odd
= vs_bline_odd
+ vsync_lines
;
1065 writel_relaxed(vs_bline_odd
,
1066 priv
->io_base
+ _REG(ENCI_DVI_VSO_BLINE_ODD
));
1068 writel_relaxed(vs_eline_odd
,
1069 priv
->io_base
+ _REG(ENCI_DVI_VSO_ELINE_ODD
));
1071 vso_begin_odd
= modulo(hs_begin
1072 + (total_pixels_venc
>> 1),
1075 writel_relaxed(vso_begin_odd
,
1076 priv
->io_base
+ _REG(ENCI_DVI_VSO_BEGIN_ODD
));
1077 writel_relaxed(vso_begin_odd
,
1078 priv
->io_base
+ _REG(ENCI_DVI_VSO_END_ODD
));
1080 vs_bline_evn
= (de_v_end_even
- 1)
1083 writel_relaxed(vs_bline_evn
,
1084 priv
->io_base
+ _REG(ENCI_DVI_VSO_BLINE_EVN
));
1086 vso_begin_evn
= modulo(hs_begin
1087 + (total_pixels_venc
>> 1),
1090 writel_relaxed(vso_begin_evn
, priv
->io_base
1091 + _REG(ENCI_DVI_VSO_BEGIN_EVN
));
1093 if (vs_bline_evn
+ vsync_lines
>= lines_f0
) {
1094 vs_eline_odd
= vs_bline_evn
1098 writel_relaxed(vs_eline_odd
, priv
->io_base
1099 + _REG(ENCI_DVI_VSO_ELINE_ODD
));
1101 writel_relaxed(vso_begin_evn
, priv
->io_base
1102 + _REG(ENCI_DVI_VSO_END_ODD
));
1104 vs_eline_evn
= vs_bline_evn
+ vsync_lines
;
1106 writel_relaxed(vs_eline_evn
, priv
->io_base
1107 + _REG(ENCI_DVI_VSO_ELINE_EVN
));
1109 writel_relaxed(vso_begin_evn
, priv
->io_base
1110 + _REG(ENCI_DVI_VSO_END_EVN
));
1114 writel_relaxed(vmode
->encp
.dvi_settings
,
1115 priv
->io_base
+ _REG(VENC_DVI_SETTING
));
1116 writel_relaxed(vmode
->encp
.video_mode
,
1117 priv
->io_base
+ _REG(ENCP_VIDEO_MODE
));
1118 writel_relaxed(vmode
->encp
.video_mode_adv
,
1119 priv
->io_base
+ _REG(ENCP_VIDEO_MODE_ADV
));
1120 if (vmode
->encp
.video_prog_mode_present
)
1121 writel_relaxed(vmode
->encp
.video_prog_mode
,
1122 priv
->io_base
+ _REG(VENC_VIDEO_PROG_MODE
));
1123 if (vmode
->encp
.video_sync_mode_present
)
1124 writel_relaxed(vmode
->encp
.video_sync_mode
,
1125 priv
->io_base
+ _REG(ENCP_VIDEO_SYNC_MODE
));
1126 if (vmode
->encp
.video_yc_dly_present
)
1127 writel_relaxed(vmode
->encp
.video_yc_dly
,
1128 priv
->io_base
+ _REG(ENCP_VIDEO_YC_DLY
));
1129 if (vmode
->encp
.video_rgb_ctrl_present
)
1130 writel_relaxed(vmode
->encp
.video_rgb_ctrl
,
1131 priv
->io_base
+ _REG(ENCP_VIDEO_RGB_CTRL
));
1132 if (vmode
->encp
.video_filt_ctrl_present
)
1133 writel_relaxed(vmode
->encp
.video_filt_ctrl
,
1134 priv
->io_base
+ _REG(ENCP_VIDEO_FILT_CTRL
));
1135 if (vmode
->encp
.video_ofld_voav_ofst_present
)
1136 writel_relaxed(vmode
->encp
.video_ofld_voav_ofst
,
1138 + _REG(ENCP_VIDEO_OFLD_VOAV_OFST
));
1139 writel_relaxed(vmode
->encp
.yfp1_htime
,
1140 priv
->io_base
+ _REG(ENCP_VIDEO_YFP1_HTIME
));
1141 writel_relaxed(vmode
->encp
.yfp2_htime
,
1142 priv
->io_base
+ _REG(ENCP_VIDEO_YFP2_HTIME
));
1143 writel_relaxed(vmode
->encp
.max_pxcnt
,
1144 priv
->io_base
+ _REG(ENCP_VIDEO_MAX_PXCNT
));
1145 writel_relaxed(vmode
->encp
.hspuls_begin
,
1146 priv
->io_base
+ _REG(ENCP_VIDEO_HSPULS_BEGIN
));
1147 writel_relaxed(vmode
->encp
.hspuls_end
,
1148 priv
->io_base
+ _REG(ENCP_VIDEO_HSPULS_END
));
1149 writel_relaxed(vmode
->encp
.hspuls_switch
,
1150 priv
->io_base
+ _REG(ENCP_VIDEO_HSPULS_SWITCH
));
1151 writel_relaxed(vmode
->encp
.vspuls_begin
,
1152 priv
->io_base
+ _REG(ENCP_VIDEO_VSPULS_BEGIN
));
1153 writel_relaxed(vmode
->encp
.vspuls_end
,
1154 priv
->io_base
+ _REG(ENCP_VIDEO_VSPULS_END
));
1155 writel_relaxed(vmode
->encp
.vspuls_bline
,
1156 priv
->io_base
+ _REG(ENCP_VIDEO_VSPULS_BLINE
));
1157 writel_relaxed(vmode
->encp
.vspuls_eline
,
1158 priv
->io_base
+ _REG(ENCP_VIDEO_VSPULS_ELINE
));
1159 if (vmode
->encp
.eqpuls_begin_present
)
1160 writel_relaxed(vmode
->encp
.eqpuls_begin
,
1161 priv
->io_base
+ _REG(ENCP_VIDEO_EQPULS_BEGIN
));
1162 if (vmode
->encp
.eqpuls_end_present
)
1163 writel_relaxed(vmode
->encp
.eqpuls_end
,
1164 priv
->io_base
+ _REG(ENCP_VIDEO_EQPULS_END
));
1165 if (vmode
->encp
.eqpuls_bline_present
)
1166 writel_relaxed(vmode
->encp
.eqpuls_bline
,
1167 priv
->io_base
+ _REG(ENCP_VIDEO_EQPULS_BLINE
));
1168 if (vmode
->encp
.eqpuls_eline_present
)
1169 writel_relaxed(vmode
->encp
.eqpuls_eline
,
1170 priv
->io_base
+ _REG(ENCP_VIDEO_EQPULS_ELINE
));
1171 writel_relaxed(vmode
->encp
.havon_begin
,
1172 priv
->io_base
+ _REG(ENCP_VIDEO_HAVON_BEGIN
));
1173 writel_relaxed(vmode
->encp
.havon_end
,
1174 priv
->io_base
+ _REG(ENCP_VIDEO_HAVON_END
));
1175 writel_relaxed(vmode
->encp
.vavon_bline
,
1176 priv
->io_base
+ _REG(ENCP_VIDEO_VAVON_BLINE
));
1177 writel_relaxed(vmode
->encp
.vavon_eline
,
1178 priv
->io_base
+ _REG(ENCP_VIDEO_VAVON_ELINE
));
1179 writel_relaxed(vmode
->encp
.hso_begin
,
1180 priv
->io_base
+ _REG(ENCP_VIDEO_HSO_BEGIN
));
1181 writel_relaxed(vmode
->encp
.hso_end
,
1182 priv
->io_base
+ _REG(ENCP_VIDEO_HSO_END
));
1183 writel_relaxed(vmode
->encp
.vso_begin
,
1184 priv
->io_base
+ _REG(ENCP_VIDEO_VSO_BEGIN
));
1185 writel_relaxed(vmode
->encp
.vso_end
,
1186 priv
->io_base
+ _REG(ENCP_VIDEO_VSO_END
));
1187 writel_relaxed(vmode
->encp
.vso_bline
,
1188 priv
->io_base
+ _REG(ENCP_VIDEO_VSO_BLINE
));
1189 if (vmode
->encp
.vso_eline_present
)
1190 writel_relaxed(vmode
->encp
.vso_eline
,
1191 priv
->io_base
+ _REG(ENCP_VIDEO_VSO_ELINE
));
1192 if (vmode
->encp
.sy_val_present
)
1193 writel_relaxed(vmode
->encp
.sy_val
,
1194 priv
->io_base
+ _REG(ENCP_VIDEO_SY_VAL
));
1195 if (vmode
->encp
.sy2_val_present
)
1196 writel_relaxed(vmode
->encp
.sy2_val
,
1197 priv
->io_base
+ _REG(ENCP_VIDEO_SY2_VAL
));
1198 writel_relaxed(vmode
->encp
.max_lncnt
,
1199 priv
->io_base
+ _REG(ENCP_VIDEO_MAX_LNCNT
));
1201 writel_relaxed(1, priv
->io_base
+ _REG(ENCP_VIDEO_EN
));
1203 /* Set DE signal’s polarity is active high */
1204 writel_bits_relaxed(BIT(14), BIT(14),
1205 priv
->io_base
+ _REG(ENCP_VIDEO_MODE
));
1207 /* Program DE timing */
1208 de_h_begin
= modulo(readl_relaxed(priv
->io_base
+
1209 _REG(ENCP_VIDEO_HAVON_BEGIN
))
1210 + venc_hdmi_latency
,
1212 de_h_end
= modulo(de_h_begin
+ active_pixels_venc
,
1215 writel_relaxed(de_h_begin
,
1216 priv
->io_base
+ _REG(ENCP_DE_H_BEGIN
));
1217 writel_relaxed(de_h_end
,
1218 priv
->io_base
+ _REG(ENCP_DE_H_END
));
1220 /* Program DE timing for even field */
1221 de_v_begin_even
= readl_relaxed(priv
->io_base
1222 + _REG(ENCP_VIDEO_VAVON_BLINE
));
1223 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
1224 de_v_end_even
= de_v_begin_even
+
1225 (mode
->vdisplay
/ 2);
1227 de_v_end_even
= de_v_begin_even
+ mode
->vdisplay
;
1229 writel_relaxed(de_v_begin_even
,
1230 priv
->io_base
+ _REG(ENCP_DE_V_BEGIN_EVEN
));
1231 writel_relaxed(de_v_end_even
,
1232 priv
->io_base
+ _REG(ENCP_DE_V_END_EVEN
));
1234 /* Program DE timing for odd field if needed */
1235 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
) {
1236 unsigned int ofld_voav_ofst
=
1237 readl_relaxed(priv
->io_base
+
1238 _REG(ENCP_VIDEO_OFLD_VOAV_OFST
));
1239 de_v_begin_odd
= to_signed((ofld_voav_ofst
& 0xf0) >> 4)
1241 + ((mode
->vtotal
- 1) / 2);
1242 de_v_end_odd
= de_v_begin_odd
+ (mode
->vdisplay
/ 2);
1244 writel_relaxed(de_v_begin_odd
,
1245 priv
->io_base
+ _REG(ENCP_DE_V_BEGIN_ODD
));
1246 writel_relaxed(de_v_end_odd
,
1247 priv
->io_base
+ _REG(ENCP_DE_V_END_ODD
));
1250 /* Program Hsync timing */
1251 if ((de_h_end
+ front_porch_venc
) >= total_pixels_venc
) {
1254 - total_pixels_venc
;
1262 hs_end
= modulo(hs_begin
+ hsync_pixels_venc
,
1265 writel_relaxed(hs_begin
,
1266 priv
->io_base
+ _REG(ENCP_DVI_HSO_BEGIN
));
1267 writel_relaxed(hs_end
,
1268 priv
->io_base
+ _REG(ENCP_DVI_HSO_END
));
1270 /* Program Vsync timing for even field */
1271 if (de_v_begin_even
>=
1272 (sof_lines
+ vsync_lines
+ (1 - vs_adjust
)))
1273 vs_bline_evn
= de_v_begin_even
1278 vs_bline_evn
= mode
->vtotal
1284 vs_eline_evn
= modulo(vs_bline_evn
+ vsync_lines
,
1287 writel_relaxed(vs_bline_evn
,
1288 priv
->io_base
+ _REG(ENCP_DVI_VSO_BLINE_EVN
));
1289 writel_relaxed(vs_eline_evn
,
1290 priv
->io_base
+ _REG(ENCP_DVI_VSO_ELINE_EVN
));
1292 vso_begin_evn
= hs_begin
;
1293 writel_relaxed(vso_begin_evn
,
1294 priv
->io_base
+ _REG(ENCP_DVI_VSO_BEGIN_EVN
));
1295 writel_relaxed(vso_begin_evn
,
1296 priv
->io_base
+ _REG(ENCP_DVI_VSO_END_EVN
));
1298 /* Program Vsync timing for odd field if needed */
1299 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
) {
1300 vs_bline_odd
= (de_v_begin_odd
- 1)
1303 vs_eline_odd
= (de_v_begin_odd
- 1)
1305 vso_begin_odd
= modulo(hs_begin
1306 + (total_pixels_venc
>> 1),
1309 writel_relaxed(vs_bline_odd
,
1310 priv
->io_base
+ _REG(ENCP_DVI_VSO_BLINE_ODD
));
1311 writel_relaxed(vs_eline_odd
,
1312 priv
->io_base
+ _REG(ENCP_DVI_VSO_ELINE_ODD
));
1313 writel_relaxed(vso_begin_odd
,
1314 priv
->io_base
+ _REG(ENCP_DVI_VSO_BEGIN_ODD
));
1315 writel_relaxed(vso_begin_odd
,
1316 priv
->io_base
+ _REG(ENCP_DVI_VSO_END_ODD
));
1319 /* Select ENCP for VIU */
1320 meson_vpp_setup_mux(priv
, MESON_VIU_VPP_MUX_ENCP
);
1323 writel_relaxed((use_enci
? 1 : 2) |
1324 (mode
->flags
& DRM_MODE_FLAG_PHSYNC
? 1 << 2 : 0) |
1325 (mode
->flags
& DRM_MODE_FLAG_PVSYNC
? 1 << 3 : 0) |
1327 (venc_repeat
? 1 << 8 : 0) |
1328 (hdmi_repeat
? 1 << 12 : 0),
1329 priv
->io_base
+ _REG(VPU_HDMI_SETTING
));
1331 priv
->venc
.hdmi_repeat
= hdmi_repeat
;
1332 priv
->venc
.venc_repeat
= venc_repeat
;
1333 priv
->venc
.hdmi_use_enci
= use_enci
;
1335 priv
->venc
.current_mode
= MESON_VENC_MODE_HDMI
;
1337 EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set
);
1339 void meson_venci_cvbs_mode_set(struct meson_drm
*priv
,
1340 struct meson_cvbs_enci_mode
*mode
)
1342 if (mode
->mode_tag
== priv
->venc
.current_mode
)
1345 /* CVBS Filter settings */
1346 writel_relaxed(0x12, priv
->io_base
+ _REG(ENCI_CFILT_CTRL
));
1347 writel_relaxed(0x12, priv
->io_base
+ _REG(ENCI_CFILT_CTRL2
));
1349 /* Digital Video Select : Interlace, clk27 clk, external */
1350 writel_relaxed(0, priv
->io_base
+ _REG(VENC_DVI_SETTING
));
1352 /* Reset Video Mode */
1353 writel_relaxed(0, priv
->io_base
+ _REG(ENCI_VIDEO_MODE
));
1354 writel_relaxed(0, priv
->io_base
+ _REG(ENCI_VIDEO_MODE_ADV
));
1356 /* Horizontal sync signal output */
1357 writel_relaxed(mode
->hso_begin
,
1358 priv
->io_base
+ _REG(ENCI_SYNC_HSO_BEGIN
));
1359 writel_relaxed(mode
->hso_end
,
1360 priv
->io_base
+ _REG(ENCI_SYNC_HSO_END
));
1362 /* Vertical Sync lines */
1363 writel_relaxed(mode
->vso_even
,
1364 priv
->io_base
+ _REG(ENCI_SYNC_VSO_EVNLN
));
1365 writel_relaxed(mode
->vso_odd
,
1366 priv
->io_base
+ _REG(ENCI_SYNC_VSO_ODDLN
));
1368 /* Macrovision max amplitude change */
1369 writel_relaxed(0x8100 + mode
->macv_max_amp
,
1370 priv
->io_base
+ _REG(ENCI_MACV_MAX_AMP
));
1373 writel_relaxed(mode
->video_prog_mode
,
1374 priv
->io_base
+ _REG(VENC_VIDEO_PROG_MODE
));
1375 writel_relaxed(mode
->video_mode
,
1376 priv
->io_base
+ _REG(ENCI_VIDEO_MODE
));
1378 /* Advanced Video Mode :
1379 * Demux shifting 0x2
1380 * Blank line end at line17/22
1381 * High bandwidth Luma Filter
1382 * Low bandwidth Chroma Filter
1383 * Bypass luma low pass filter
1384 * No macrovision on CSYNC
1386 writel_relaxed(0x26, priv
->io_base
+ _REG(ENCI_VIDEO_MODE_ADV
));
1388 writel(mode
->sch_adjust
, priv
->io_base
+ _REG(ENCI_VIDEO_SCH
));
1390 /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
1391 writel_relaxed(0x07, priv
->io_base
+ _REG(ENCI_SYNC_MODE
));
1393 /* 0x3 Y, C, and Component Y delay */
1394 writel_relaxed(mode
->yc_delay
, priv
->io_base
+ _REG(ENCI_YC_DELAY
));
1397 writel_relaxed(mode
->pixel_start
,
1398 priv
->io_base
+ _REG(ENCI_VFIFO2VD_PIXEL_START
));
1399 writel_relaxed(mode
->pixel_end
,
1400 priv
->io_base
+ _REG(ENCI_VFIFO2VD_PIXEL_END
));
1402 writel_relaxed(mode
->top_field_line_start
,
1403 priv
->io_base
+ _REG(ENCI_VFIFO2VD_LINE_TOP_START
));
1404 writel_relaxed(mode
->top_field_line_end
,
1405 priv
->io_base
+ _REG(ENCI_VFIFO2VD_LINE_TOP_END
));
1407 writel_relaxed(mode
->bottom_field_line_start
,
1408 priv
->io_base
+ _REG(ENCI_VFIFO2VD_LINE_BOT_START
));
1409 writel_relaxed(mode
->bottom_field_line_end
,
1410 priv
->io_base
+ _REG(ENCI_VFIFO2VD_LINE_BOT_END
));
1412 /* Internal Venc, Internal VIU Sync, Internal Vencoder */
1413 writel_relaxed(0, priv
->io_base
+ _REG(VENC_SYNC_ROUTE
));
1415 /* UNreset Interlaced TV Encoder */
1416 writel_relaxed(0, priv
->io_base
+ _REG(ENCI_DBG_PX_RST
));
1418 /* Enable Vfifo2vd, Y_Cb_Y_Cr select */
1419 writel_relaxed(0x4e01, priv
->io_base
+ _REG(ENCI_VFIFO2VD_CTL
));
1422 writel_relaxed(0, priv
->io_base
+ _REG(VENC_VDAC_SETTING
));
1424 /* Video Upsampling */
1425 writel_relaxed(0x0061, priv
->io_base
+ _REG(VENC_UPSAMPLE_CTRL0
));
1426 writel_relaxed(0x4061, priv
->io_base
+ _REG(VENC_UPSAMPLE_CTRL1
));
1427 writel_relaxed(0x5061, priv
->io_base
+ _REG(VENC_UPSAMPLE_CTRL2
));
1429 /* Select Interlace Y DACs */
1430 writel_relaxed(0, priv
->io_base
+ _REG(VENC_VDAC_DACSEL0
));
1431 writel_relaxed(0, priv
->io_base
+ _REG(VENC_VDAC_DACSEL1
));
1432 writel_relaxed(0, priv
->io_base
+ _REG(VENC_VDAC_DACSEL2
));
1433 writel_relaxed(0, priv
->io_base
+ _REG(VENC_VDAC_DACSEL3
));
1434 writel_relaxed(0, priv
->io_base
+ _REG(VENC_VDAC_DACSEL4
));
1435 writel_relaxed(0, priv
->io_base
+ _REG(VENC_VDAC_DACSEL5
));
1437 /* Select ENCI for VIU */
1438 meson_vpp_setup_mux(priv
, MESON_VIU_VPP_MUX_ENCI
);
1440 /* Enable ENCI FIFO */
1441 writel_relaxed(0x2000, priv
->io_base
+ _REG(VENC_VDAC_FIFO_CTRL
));
1443 /* Select ENCI DACs 0, 1, 4, and 5 */
1444 writel_relaxed(0x11, priv
->io_base
+ _REG(ENCI_DACSEL_0
));
1445 writel_relaxed(0x11, priv
->io_base
+ _REG(ENCI_DACSEL_1
));
1447 /* Interlace video enable */
1448 writel_relaxed(1, priv
->io_base
+ _REG(ENCI_VIDEO_EN
));
1450 /* Configure Video Saturation / Contrast / Brightness / Hue */
1451 writel_relaxed(mode
->video_saturation
,
1452 priv
->io_base
+ _REG(ENCI_VIDEO_SAT
));
1453 writel_relaxed(mode
->video_contrast
,
1454 priv
->io_base
+ _REG(ENCI_VIDEO_CONT
));
1455 writel_relaxed(mode
->video_brightness
,
1456 priv
->io_base
+ _REG(ENCI_VIDEO_BRIGHT
));
1457 writel_relaxed(mode
->video_hue
,
1458 priv
->io_base
+ _REG(ENCI_VIDEO_HUE
));
1460 /* Enable DAC0 Filter */
1461 writel_relaxed(0x1, priv
->io_base
+ _REG(VENC_VDAC_DAC0_FILT_CTRL0
));
1462 writel_relaxed(0xfc48, priv
->io_base
+ _REG(VENC_VDAC_DAC0_FILT_CTRL1
));
1464 /* 0 in Macrovision register 0 */
1465 writel_relaxed(0, priv
->io_base
+ _REG(ENCI_MACV_N0
));
1467 /* Analog Synchronization and color burst value adjust */
1468 writel_relaxed(mode
->analog_sync_adj
,
1469 priv
->io_base
+ _REG(ENCI_SYNC_ADJ
));
1471 priv
->venc
.current_mode
= mode
->mode_tag
;
1474 /* Returns the current ENCI field polarity */
1475 unsigned int meson_venci_get_field(struct meson_drm
*priv
)
1477 return readl_relaxed(priv
->io_base
+ _REG(ENCI_INFO_READ
)) & BIT(29);
1480 void meson_venc_enable_vsync(struct meson_drm
*priv
)
1482 writel_relaxed(2, priv
->io_base
+ _REG(VENC_INTCTRL
));
1485 void meson_venc_disable_vsync(struct meson_drm
*priv
)
1487 writel_relaxed(0, priv
->io_base
+ _REG(VENC_INTCTRL
));
1490 void meson_venc_init(struct meson_drm
*priv
)
1492 /* Disable CVBS VDAC */
1493 regmap_write(priv
->hhi
, HHI_VDAC_CNTL0
, 0);
1494 regmap_write(priv
->hhi
, HHI_VDAC_CNTL1
, 8);
1496 /* Power Down Dacs */
1497 writel_relaxed(0xff, priv
->io_base
+ _REG(VENC_VDAC_SETTING
));
1499 /* Disable HDMI PHY */
1500 regmap_write(priv
->hhi
, HHI_HDMI_PHY_CNTL0
, 0);
1503 writel_bits_relaxed(0x3, 0,
1504 priv
->io_base
+ _REG(VPU_HDMI_SETTING
));
1506 /* Disable all encoders */
1507 writel_relaxed(0, priv
->io_base
+ _REG(ENCI_VIDEO_EN
));
1508 writel_relaxed(0, priv
->io_base
+ _REG(ENCP_VIDEO_EN
));
1509 writel_relaxed(0, priv
->io_base
+ _REG(ENCL_VIDEO_EN
));
1511 /* Disable VSync IRQ */
1512 meson_venc_disable_vsync(priv
);
1514 priv
->venc
.current_mode
= MESON_VENC_MODE_NONE
;