Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2016 BayLibre, SAS
0004  * Author: Neil Armstrong <narmstrong@baylibre.com>
0005  * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
0006  */
0007 
0008 #include <linux/export.h>
0009 
0010 #include <drm/drm_modes.h>
0011 
0012 #include "meson_drv.h"
0013 #include "meson_registers.h"
0014 #include "meson_venc.h"
0015 #include "meson_vpp.h"
0016 
0017 /**
0018  * DOC: Video Encoder
0019  *
0020  * VENC Handle the pixels encoding to the output formats.
0021  * We handle the following encodings :
0022  *
0023  * - CVBS Encoding via the ENCI encoder and VDAC digital to analog converter
0024  * - TMDS/HDMI Encoding via ENCI_DIV and ENCP
0025  * - Setup of more clock rates for HDMI modes
0026  *
0027  * What is missing :
0028  *
0029  * - LCD Panel encoding via ENCL
0030  * - TV Panel encoding via ENCT
0031  *
0032  * VENC paths :
0033  *
0034  * .. code::
0035  *
0036  *          _____   _____   ____________________
0037  *   vd1---|     |-|     | | VENC     /---------|----VDAC
0038  *   vd2---| VIU |-| VPP |-|-----ENCI/-ENCI_DVI-|-|
0039  *   osd1--|     |-|     | | \                  | X--HDMI-TX
0040  *   osd2--|_____|-|_____| |  |\-ENCP--ENCP_DVI-|-|
0041  *                         |  |                 |
0042  *                         |  \--ENCL-----------|----LVDS
0043  *                         |____________________|
0044  *
0045  * The ENCI is designed for PAl or NTSC encoding and can go through the VDAC
0046  * directly for CVBS encoding or through the ENCI_DVI encoder for HDMI.
0047  * The ENCP is designed for Progressive encoding but can also generate
0048  * 1080i interlaced pixels, and was initially designed to encode pixels for
0049  * VDAC to output RGB ou YUV analog outputs.
0050  * It's output is only used through the ENCP_DVI encoder for HDMI.
0051  * The ENCL LVDS encoder is not implemented.
0052  *
0053  * The ENCI and ENCP encoders needs specially defined parameters for each
0054  * supported mode and thus cannot be determined from standard video timings.
0055  *
0056  * The ENCI end ENCP DVI encoders are more generic and can generate any timings
0057  * from the pixel data generated by ENCI or ENCP, so can use the standard video
0058  * timings are source for HW parameters.
0059  */
0060 
0061 /* HHI Registers */
0062 #define HHI_GCLK_MPEG2      0x148 /* 0x52 offset in data sheet */
0063 #define HHI_VDAC_CNTL0      0x2F4 /* 0xbd offset in data sheet */
0064 #define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbb offset in data sheet */
0065 #define HHI_VDAC_CNTL1      0x2F8 /* 0xbe offset in data sheet */
0066 #define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbc offset in data sheet */
0067 #define HHI_HDMI_PHY_CNTL0  0x3a0 /* 0xe8 offset in data sheet */
0068 
0069 struct meson_cvbs_enci_mode meson_cvbs_enci_pal = {
0070     .mode_tag = MESON_VENC_MODE_CVBS_PAL,
0071     .hso_begin = 3,
0072     .hso_end = 129,
0073     .vso_even = 3,
0074     .vso_odd = 260,
0075     .macv_max_amp = 7,
0076     .video_prog_mode = 0xff,
0077     .video_mode = 0x13,
0078     .sch_adjust = 0x28,
0079     .yc_delay = 0x343,
0080     .pixel_start = 251,
0081     .pixel_end = 1691,
0082     .top_field_line_start = 22,
0083     .top_field_line_end = 310,
0084     .bottom_field_line_start = 23,
0085     .bottom_field_line_end = 311,
0086     .video_saturation = 9,
0087     .video_contrast = 0,
0088     .video_brightness = 0,
0089     .video_hue = 0,
0090     .analog_sync_adj = 0x8080,
0091 };
0092 
0093 struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc = {
0094     .mode_tag = MESON_VENC_MODE_CVBS_NTSC,
0095     .hso_begin = 5,
0096     .hso_end = 129,
0097     .vso_even = 3,
0098     .vso_odd = 260,
0099     .macv_max_amp = 0xb,
0100     .video_prog_mode = 0xf0,
0101     .video_mode = 0x8,
0102     .sch_adjust = 0x20,
0103     .yc_delay = 0x333,
0104     .pixel_start = 227,
0105     .pixel_end = 1667,
0106     .top_field_line_start = 18,
0107     .top_field_line_end = 258,
0108     .bottom_field_line_start = 19,
0109     .bottom_field_line_end = 259,
0110     .video_saturation = 18,
0111     .video_contrast = 3,
0112     .video_brightness = 0,
0113     .video_hue = 0,
0114     .analog_sync_adj = 0x9c00,
0115 };
0116 
0117 union meson_hdmi_venc_mode {
0118     struct {
0119         unsigned int mode_tag;
0120         unsigned int hso_begin;
0121         unsigned int hso_end;
0122         unsigned int vso_even;
0123         unsigned int vso_odd;
0124         unsigned int macv_max_amp;
0125         unsigned int video_prog_mode;
0126         unsigned int video_mode;
0127         unsigned int sch_adjust;
0128         unsigned int yc_delay;
0129         unsigned int pixel_start;
0130         unsigned int pixel_end;
0131         unsigned int top_field_line_start;
0132         unsigned int top_field_line_end;
0133         unsigned int bottom_field_line_start;
0134         unsigned int bottom_field_line_end;
0135     } enci;
0136     struct {
0137         unsigned int dvi_settings;
0138         unsigned int video_mode;
0139         unsigned int video_mode_adv;
0140         unsigned int video_prog_mode;
0141         bool video_prog_mode_present;
0142         unsigned int video_sync_mode;
0143         bool video_sync_mode_present;
0144         unsigned int video_yc_dly;
0145         bool video_yc_dly_present;
0146         unsigned int video_rgb_ctrl;
0147         bool video_rgb_ctrl_present;
0148         unsigned int video_filt_ctrl;
0149         bool video_filt_ctrl_present;
0150         unsigned int video_ofld_voav_ofst;
0151         bool video_ofld_voav_ofst_present;
0152         unsigned int yfp1_htime;
0153         unsigned int yfp2_htime;
0154         unsigned int max_pxcnt;
0155         unsigned int hspuls_begin;
0156         unsigned int hspuls_end;
0157         unsigned int hspuls_switch;
0158         unsigned int vspuls_begin;
0159         unsigned int vspuls_end;
0160         unsigned int vspuls_bline;
0161         unsigned int vspuls_eline;
0162         unsigned int eqpuls_begin;
0163         bool eqpuls_begin_present;
0164         unsigned int eqpuls_end;
0165         bool eqpuls_end_present;
0166         unsigned int eqpuls_bline;
0167         bool eqpuls_bline_present;
0168         unsigned int eqpuls_eline;
0169         bool eqpuls_eline_present;
0170         unsigned int havon_begin;
0171         unsigned int havon_end;
0172         unsigned int vavon_bline;
0173         unsigned int vavon_eline;
0174         unsigned int hso_begin;
0175         unsigned int hso_end;
0176         unsigned int vso_begin;
0177         unsigned int vso_end;
0178         unsigned int vso_bline;
0179         unsigned int vso_eline;
0180         bool vso_eline_present;
0181         unsigned int sy_val;
0182         bool sy_val_present;
0183         unsigned int sy2_val;
0184         bool sy2_val_present;
0185         unsigned int max_lncnt;
0186     } encp;
0187 };
0188 
0189 union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = {
0190     .enci = {
0191         .hso_begin = 5,
0192         .hso_end = 129,
0193         .vso_even = 3,
0194         .vso_odd = 260,
0195         .macv_max_amp = 0xb,
0196         .video_prog_mode = 0xf0,
0197         .video_mode = 0x8,
0198         .sch_adjust = 0x20,
0199         .yc_delay = 0,
0200         .pixel_start = 227,
0201         .pixel_end = 1667,
0202         .top_field_line_start = 18,
0203         .top_field_line_end = 258,
0204         .bottom_field_line_start = 19,
0205         .bottom_field_line_end = 259,
0206     },
0207 };
0208 
0209 union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = {
0210     .enci = {
0211         .hso_begin = 3,
0212         .hso_end = 129,
0213         .vso_even = 3,
0214         .vso_odd = 260,
0215         .macv_max_amp = 0x7,
0216         .video_prog_mode = 0xff,
0217         .video_mode = 0x13,
0218         .sch_adjust = 0x28,
0219         .yc_delay = 0x333,
0220         .pixel_start = 251,
0221         .pixel_end = 1691,
0222         .top_field_line_start = 22,
0223         .top_field_line_end = 310,
0224         .bottom_field_line_start = 23,
0225         .bottom_field_line_end = 311,
0226     },
0227 };
0228 
0229 union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p = {
0230     .encp = {
0231         .dvi_settings = 0x21,
0232         .video_mode = 0x4000,
0233         .video_mode_adv = 0x9,
0234         .video_prog_mode = 0,
0235         .video_prog_mode_present = true,
0236         .video_sync_mode = 7,
0237         .video_sync_mode_present = true,
0238         /* video_yc_dly */
0239         /* video_rgb_ctrl */
0240         .video_filt_ctrl = 0x2052,
0241         .video_filt_ctrl_present = true,
0242         /* video_ofld_voav_ofst */
0243         .yfp1_htime = 244,
0244         .yfp2_htime = 1630,
0245         .max_pxcnt = 1715,
0246         .hspuls_begin = 0x22,
0247         .hspuls_end = 0xa0,
0248         .hspuls_switch = 88,
0249         .vspuls_begin = 0,
0250         .vspuls_end = 1589,
0251         .vspuls_bline = 0,
0252         .vspuls_eline = 5,
0253         .havon_begin = 249,
0254         .havon_end = 1689,
0255         .vavon_bline = 42,
0256         .vavon_eline = 521,
0257         /* eqpuls_begin */
0258         /* eqpuls_end */
0259         /* eqpuls_bline */
0260         /* eqpuls_eline */
0261         .hso_begin = 3,
0262         .hso_end = 5,
0263         .vso_begin = 3,
0264         .vso_end = 5,
0265         .vso_bline = 0,
0266         /* vso_eline */
0267         .sy_val = 8,
0268         .sy_val_present = true,
0269         .sy2_val = 0x1d8,
0270         .sy2_val_present = true,
0271         .max_lncnt = 524,
0272     },
0273 };
0274 
0275 union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p = {
0276     .encp = {
0277         .dvi_settings = 0x21,
0278         .video_mode = 0x4000,
0279         .video_mode_adv = 0x9,
0280         .video_prog_mode = 0,
0281         .video_prog_mode_present = true,
0282         .video_sync_mode = 7,
0283         .video_sync_mode_present = true,
0284         /* video_yc_dly */
0285         /* video_rgb_ctrl */
0286         .video_filt_ctrl = 0x52,
0287         .video_filt_ctrl_present = true,
0288         /* video_ofld_voav_ofst */
0289         .yfp1_htime = 235,
0290         .yfp2_htime = 1674,
0291         .max_pxcnt = 1727,
0292         .hspuls_begin = 0,
0293         .hspuls_end = 0x80,
0294         .hspuls_switch = 88,
0295         .vspuls_begin = 0,
0296         .vspuls_end = 1599,
0297         .vspuls_bline = 0,
0298         .vspuls_eline = 4,
0299         .havon_begin = 235,
0300         .havon_end = 1674,
0301         .vavon_bline = 44,
0302         .vavon_eline = 619,
0303         /* eqpuls_begin */
0304         /* eqpuls_end */
0305         /* eqpuls_bline */
0306         /* eqpuls_eline */
0307         .hso_begin = 0x80,
0308         .hso_end = 0,
0309         .vso_begin = 0,
0310         .vso_end = 5,
0311         .vso_bline = 0,
0312         /* vso_eline */
0313         .sy_val = 8,
0314         .sy_val_present = true,
0315         .sy2_val = 0x1d8,
0316         .sy2_val_present = true,
0317         .max_lncnt = 624,
0318     },
0319 };
0320 
0321 union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60 = {
0322     .encp = {
0323         .dvi_settings = 0x2029,
0324         .video_mode = 0x4040,
0325         .video_mode_adv = 0x19,
0326         /* video_prog_mode */
0327         /* video_sync_mode */
0328         /* video_yc_dly */
0329         /* video_rgb_ctrl */
0330         /* video_filt_ctrl */
0331         /* video_ofld_voav_ofst */
0332         .yfp1_htime = 648,
0333         .yfp2_htime = 3207,
0334         .max_pxcnt = 3299,
0335         .hspuls_begin = 80,
0336         .hspuls_end = 240,
0337         .hspuls_switch = 80,
0338         .vspuls_begin = 688,
0339         .vspuls_end = 3248,
0340         .vspuls_bline = 4,
0341         .vspuls_eline = 8,
0342         .havon_begin = 648,
0343         .havon_end = 3207,
0344         .vavon_bline = 29,
0345         .vavon_eline = 748,
0346         /* eqpuls_begin */
0347         /* eqpuls_end */
0348         /* eqpuls_bline */
0349         /* eqpuls_eline */
0350         .hso_begin = 256,
0351         .hso_end = 168,
0352         .vso_begin = 168,
0353         .vso_end = 256,
0354         .vso_bline = 0,
0355         .vso_eline = 5,
0356         .vso_eline_present = true,
0357         /* sy_val */
0358         /* sy2_val */
0359         .max_lncnt = 749,
0360     },
0361 };
0362 
0363 union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50 = {
0364     .encp = {
0365         .dvi_settings = 0x202d,
0366         .video_mode = 0x4040,
0367         .video_mode_adv = 0x19,
0368         .video_prog_mode = 0x100,
0369         .video_prog_mode_present = true,
0370         .video_sync_mode = 0x407,
0371         .video_sync_mode_present = true,
0372         .video_yc_dly = 0,
0373         .video_yc_dly_present = true,
0374         /* video_rgb_ctrl */
0375         /* video_filt_ctrl */
0376         /* video_ofld_voav_ofst */
0377         .yfp1_htime = 648,
0378         .yfp2_htime = 3207,
0379         .max_pxcnt = 3959,
0380         .hspuls_begin = 80,
0381         .hspuls_end = 240,
0382         .hspuls_switch = 80,
0383         .vspuls_begin = 688,
0384         .vspuls_end = 3248,
0385         .vspuls_bline = 4,
0386         .vspuls_eline = 8,
0387         .havon_begin = 648,
0388         .havon_end = 3207,
0389         .vavon_bline = 29,
0390         .vavon_eline = 748,
0391         /* eqpuls_begin */
0392         /* eqpuls_end */
0393         /* eqpuls_bline */
0394         /* eqpuls_eline */
0395         .hso_begin = 128,
0396         .hso_end = 208,
0397         .vso_begin = 128,
0398         .vso_end = 128,
0399         .vso_bline = 0,
0400         .vso_eline = 5,
0401         .vso_eline_present = true,
0402         /* sy_val */
0403         /* sy2_val */
0404         .max_lncnt = 749,
0405     },
0406 };
0407 
0408 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60 = {
0409     .encp = {
0410         .dvi_settings = 0x2029,
0411         .video_mode = 0x5ffc,
0412         .video_mode_adv = 0x19,
0413         .video_prog_mode = 0x100,
0414         .video_prog_mode_present = true,
0415         .video_sync_mode = 0x207,
0416         .video_sync_mode_present = true,
0417         /* video_yc_dly */
0418         /* video_rgb_ctrl */
0419         /* video_filt_ctrl */
0420         .video_ofld_voav_ofst = 0x11,
0421         .video_ofld_voav_ofst_present = true,
0422         .yfp1_htime = 516,
0423         .yfp2_htime = 4355,
0424         .max_pxcnt = 4399,
0425         .hspuls_begin = 88,
0426         .hspuls_end = 264,
0427         .hspuls_switch = 88,
0428         .vspuls_begin = 440,
0429         .vspuls_end = 2200,
0430         .vspuls_bline = 0,
0431         .vspuls_eline = 4,
0432         .havon_begin = 516,
0433         .havon_end = 4355,
0434         .vavon_bline = 20,
0435         .vavon_eline = 559,
0436         .eqpuls_begin = 2288,
0437         .eqpuls_begin_present = true,
0438         .eqpuls_end = 2464,
0439         .eqpuls_end_present = true,
0440         .eqpuls_bline = 0,
0441         .eqpuls_bline_present = true,
0442         .eqpuls_eline = 4,
0443         .eqpuls_eline_present = true,
0444         .hso_begin = 264,
0445         .hso_end = 176,
0446         .vso_begin = 88,
0447         .vso_end = 88,
0448         .vso_bline = 0,
0449         .vso_eline = 5,
0450         .vso_eline_present = true,
0451         /* sy_val */
0452         /* sy2_val */
0453         .max_lncnt = 1124,
0454     },
0455 };
0456 
0457 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50 = {
0458     .encp = {
0459         .dvi_settings = 0x202d,
0460         .video_mode = 0x5ffc,
0461         .video_mode_adv = 0x19,
0462         .video_prog_mode = 0x100,
0463         .video_prog_mode_present = true,
0464         .video_sync_mode = 0x7,
0465         .video_sync_mode_present = true,
0466         /* video_yc_dly */
0467         /* video_rgb_ctrl */
0468         /* video_filt_ctrl */
0469         .video_ofld_voav_ofst = 0x11,
0470         .video_ofld_voav_ofst_present = true,
0471         .yfp1_htime = 526,
0472         .yfp2_htime = 4365,
0473         .max_pxcnt = 5279,
0474         .hspuls_begin = 88,
0475         .hspuls_end = 264,
0476         .hspuls_switch = 88,
0477         .vspuls_begin = 440,
0478         .vspuls_end = 2200,
0479         .vspuls_bline = 0,
0480         .vspuls_eline = 4,
0481         .havon_begin = 526,
0482         .havon_end = 4365,
0483         .vavon_bline = 20,
0484         .vavon_eline = 559,
0485         .eqpuls_begin = 2288,
0486         .eqpuls_begin_present = true,
0487         .eqpuls_end = 2464,
0488         .eqpuls_end_present = true,
0489         .eqpuls_bline = 0,
0490         .eqpuls_bline_present = true,
0491         .eqpuls_eline = 4,
0492         .eqpuls_eline_present = true,
0493         .hso_begin = 142,
0494         .hso_end = 230,
0495         .vso_begin = 142,
0496         .vso_end = 142,
0497         .vso_bline = 0,
0498         .vso_eline = 5,
0499         .vso_eline_present = true,
0500         /* sy_val */
0501         /* sy2_val */
0502         .max_lncnt = 1124,
0503     },
0504 };
0505 
0506 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24 = {
0507     .encp = {
0508         .dvi_settings = 0xd,
0509         .video_mode = 0x4040,
0510         .video_mode_adv = 0x18,
0511         .video_prog_mode = 0x100,
0512         .video_prog_mode_present = true,
0513         .video_sync_mode = 0x7,
0514         .video_sync_mode_present = true,
0515         .video_yc_dly = 0,
0516         .video_yc_dly_present = true,
0517         .video_rgb_ctrl = 2,
0518         .video_rgb_ctrl_present = true,
0519         .video_filt_ctrl = 0x1052,
0520         .video_filt_ctrl_present = true,
0521         /* video_ofld_voav_ofst */
0522         .yfp1_htime = 271,
0523         .yfp2_htime = 2190,
0524         .max_pxcnt = 2749,
0525         .hspuls_begin = 44,
0526         .hspuls_end = 132,
0527         .hspuls_switch = 44,
0528         .vspuls_begin = 220,
0529         .vspuls_end = 2140,
0530         .vspuls_bline = 0,
0531         .vspuls_eline = 4,
0532         .havon_begin = 271,
0533         .havon_end = 2190,
0534         .vavon_bline = 41,
0535         .vavon_eline = 1120,
0536         /* eqpuls_begin */
0537         /* eqpuls_end */
0538         .eqpuls_bline = 0,
0539         .eqpuls_bline_present = true,
0540         .eqpuls_eline = 4,
0541         .eqpuls_eline_present = true,
0542         .hso_begin = 79,
0543         .hso_end = 123,
0544         .vso_begin = 79,
0545         .vso_end = 79,
0546         .vso_bline = 0,
0547         .vso_eline = 5,
0548         .vso_eline_present = true,
0549         /* sy_val */
0550         /* sy2_val */
0551         .max_lncnt = 1124,
0552     },
0553 };
0554 
0555 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30 = {
0556     .encp = {
0557         .dvi_settings = 0x1,
0558         .video_mode = 0x4040,
0559         .video_mode_adv = 0x18,
0560         .video_prog_mode = 0x100,
0561         .video_prog_mode_present = true,
0562         /* video_sync_mode */
0563         /* video_yc_dly */
0564         /* video_rgb_ctrl */
0565         .video_filt_ctrl = 0x1052,
0566         .video_filt_ctrl_present = true,
0567         /* video_ofld_voav_ofst */
0568         .yfp1_htime = 140,
0569         .yfp2_htime = 2060,
0570         .max_pxcnt = 2199,
0571         .hspuls_begin = 2156,
0572         .hspuls_end = 44,
0573         .hspuls_switch = 44,
0574         .vspuls_begin = 140,
0575         .vspuls_end = 2059,
0576         .vspuls_bline = 0,
0577         .vspuls_eline = 4,
0578         .havon_begin = 148,
0579         .havon_end = 2067,
0580         .vavon_bline = 41,
0581         .vavon_eline = 1120,
0582         /* eqpuls_begin */
0583         /* eqpuls_end */
0584         /* eqpuls_bline */
0585         /* eqpuls_eline */
0586         .hso_begin = 44,
0587         .hso_end = 2156,
0588         .vso_begin = 2100,
0589         .vso_end = 2164,
0590         .vso_bline = 0,
0591         .vso_eline = 5,
0592         .vso_eline_present = true,
0593         /* sy_val */
0594         /* sy2_val */
0595         .max_lncnt = 1124,
0596     },
0597 };
0598 
0599 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50 = {
0600     .encp = {
0601         .dvi_settings = 0xd,
0602         .video_mode = 0x4040,
0603         .video_mode_adv = 0x18,
0604         .video_prog_mode = 0x100,
0605         .video_prog_mode_present = true,
0606         .video_sync_mode = 0x7,
0607         .video_sync_mode_present = true,
0608         .video_yc_dly = 0,
0609         .video_yc_dly_present = true,
0610         .video_rgb_ctrl = 2,
0611         .video_rgb_ctrl_present = true,
0612         /* video_filt_ctrl */
0613         /* video_ofld_voav_ofst */
0614         .yfp1_htime = 271,
0615         .yfp2_htime = 2190,
0616         .max_pxcnt = 2639,
0617         .hspuls_begin = 44,
0618         .hspuls_end = 132,
0619         .hspuls_switch = 44,
0620         .vspuls_begin = 220,
0621         .vspuls_end = 2140,
0622         .vspuls_bline = 0,
0623         .vspuls_eline = 4,
0624         .havon_begin = 271,
0625         .havon_end = 2190,
0626         .vavon_bline = 41,
0627         .vavon_eline = 1120,
0628         /* eqpuls_begin */
0629         /* eqpuls_end */
0630         .eqpuls_bline = 0,
0631         .eqpuls_bline_present = true,
0632         .eqpuls_eline = 4,
0633         .eqpuls_eline_present = true,
0634         .hso_begin = 79,
0635         .hso_end = 123,
0636         .vso_begin = 79,
0637         .vso_end = 79,
0638         .vso_bline = 0,
0639         .vso_eline = 5,
0640         .vso_eline_present = true,
0641         /* sy_val */
0642         /* sy2_val */
0643         .max_lncnt = 1124,
0644     },
0645 };
0646 
0647 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
0648     .encp = {
0649         .dvi_settings = 0x1,
0650         .video_mode = 0x4040,
0651         .video_mode_adv = 0x18,
0652         .video_prog_mode = 0x100,
0653         .video_prog_mode_present = true,
0654         /* video_sync_mode */
0655         /* video_yc_dly */
0656         /* video_rgb_ctrl */
0657         .video_filt_ctrl = 0x1052,
0658         .video_filt_ctrl_present = true,
0659         /* video_ofld_voav_ofst */
0660         .yfp1_htime = 140,
0661         .yfp2_htime = 2060,
0662         .max_pxcnt = 2199,
0663         .hspuls_begin = 2156,
0664         .hspuls_end = 44,
0665         .hspuls_switch = 44,
0666         .vspuls_begin = 140,
0667         .vspuls_end = 2059,
0668         .vspuls_bline = 0,
0669         .vspuls_eline = 4,
0670         .havon_begin = 148,
0671         .havon_end = 2067,
0672         .vavon_bline = 41,
0673         .vavon_eline = 1120,
0674         /* eqpuls_begin */
0675         /* eqpuls_end */
0676         /* eqpuls_bline */
0677         /* eqpuls_eline */
0678         .hso_begin = 44,
0679         .hso_end = 2156,
0680         .vso_begin = 2100,
0681         .vso_end = 2164,
0682         .vso_bline = 0,
0683         .vso_eline = 5,
0684         .vso_eline_present = true,
0685         /* sy_val */
0686         /* sy2_val */
0687         .max_lncnt = 1124,
0688     },
0689 };
0690 
0691 union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p24 = {
0692     .encp = {
0693         .dvi_settings = 0x1,
0694         .video_mode = 0x4040,
0695         .video_mode_adv = 0x8,
0696         /* video_sync_mode */
0697         /* video_yc_dly */
0698         /* video_rgb_ctrl */
0699         .video_filt_ctrl = 0x1000,
0700         .video_filt_ctrl_present = true,
0701         /* video_ofld_voav_ofst */
0702         .yfp1_htime = 140,
0703         .yfp2_htime = 140+3840,
0704         .max_pxcnt = 3840+1660-1,
0705         .hspuls_begin = 2156+1920,
0706         .hspuls_end = 44,
0707         .hspuls_switch = 44,
0708         .vspuls_begin = 140,
0709         .vspuls_end = 2059+1920,
0710         .vspuls_bline = 0,
0711         .vspuls_eline = 4,
0712         .havon_begin = 148,
0713         .havon_end = 3987,
0714         .vavon_bline = 89,
0715         .vavon_eline = 2248,
0716         /* eqpuls_begin */
0717         /* eqpuls_end */
0718         /* eqpuls_bline */
0719         /* eqpuls_eline */
0720         .hso_begin = 44,
0721         .hso_end = 2156+1920,
0722         .vso_begin = 2100+1920,
0723         .vso_end = 2164+1920,
0724         .vso_bline = 51,
0725         .vso_eline = 53,
0726         .vso_eline_present = true,
0727         /* sy_val */
0728         /* sy2_val */
0729         .max_lncnt = 2249,
0730     },
0731 };
0732 
0733 union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p25 = {
0734     .encp = {
0735         .dvi_settings = 0x1,
0736         .video_mode = 0x4040,
0737         .video_mode_adv = 0x8,
0738         /* video_sync_mode */
0739         /* video_yc_dly */
0740         /* video_rgb_ctrl */
0741         .video_filt_ctrl = 0x1000,
0742         .video_filt_ctrl_present = true,
0743         /* video_ofld_voav_ofst */
0744         .yfp1_htime = 140,
0745         .yfp2_htime = 140+3840,
0746         .max_pxcnt = 3840+1440-1,
0747         .hspuls_begin = 2156+1920,
0748         .hspuls_end = 44,
0749         .hspuls_switch = 44,
0750         .vspuls_begin = 140,
0751         .vspuls_end = 2059+1920,
0752         .vspuls_bline = 0,
0753         .vspuls_eline = 4,
0754         .havon_begin = 148,
0755         .havon_end = 3987,
0756         .vavon_bline = 89,
0757         .vavon_eline = 2248,
0758         /* eqpuls_begin */
0759         /* eqpuls_end */
0760         /* eqpuls_bline */
0761         /* eqpuls_eline */
0762         .hso_begin = 44,
0763         .hso_end = 2156+1920,
0764         .vso_begin = 2100+1920,
0765         .vso_end = 2164+1920,
0766         .vso_bline = 51,
0767         .vso_eline = 53,
0768         .vso_eline_present = true,
0769         /* sy_val */
0770         /* sy2_val */
0771         .max_lncnt = 2249,
0772     },
0773 };
0774 
0775 union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p30 = {
0776     .encp = {
0777         .dvi_settings = 0x1,
0778         .video_mode = 0x4040,
0779         .video_mode_adv = 0x8,
0780         /* video_sync_mode */
0781         /* video_yc_dly */
0782         /* video_rgb_ctrl */
0783         .video_filt_ctrl = 0x1000,
0784         .video_filt_ctrl_present = true,
0785         /* video_ofld_voav_ofst */
0786         .yfp1_htime = 140,
0787         .yfp2_htime = 140+3840,
0788         .max_pxcnt = 3840+560-1,
0789         .hspuls_begin = 2156+1920,
0790         .hspuls_end = 44,
0791         .hspuls_switch = 44,
0792         .vspuls_begin = 140,
0793         .vspuls_end = 2059+1920,
0794         .vspuls_bline = 0,
0795         .vspuls_eline = 4,
0796         .havon_begin = 148,
0797         .havon_end = 3987,
0798         .vavon_bline = 89,
0799         .vavon_eline = 2248,
0800         /* eqpuls_begin */
0801         /* eqpuls_end */
0802         /* eqpuls_bline */
0803         /* eqpuls_eline */
0804         .hso_begin = 44,
0805         .hso_end = 2156+1920,
0806         .vso_begin = 2100+1920,
0807         .vso_end = 2164+1920,
0808         .vso_bline = 51,
0809         .vso_eline = 53,
0810         .vso_eline_present = true,
0811         /* sy_val */
0812         /* sy2_val */
0813         .max_lncnt = 2249,
0814     },
0815 };
0816 
0817 struct meson_hdmi_venc_vic_mode {
0818     unsigned int vic;
0819     union meson_hdmi_venc_mode *mode;
0820 } meson_hdmi_venc_vic_modes[] = {
0821     { 6, &meson_hdmi_enci_mode_480i },
0822     { 7, &meson_hdmi_enci_mode_480i },
0823     { 21, &meson_hdmi_enci_mode_576i },
0824     { 22, &meson_hdmi_enci_mode_576i },
0825     { 2, &meson_hdmi_encp_mode_480p },
0826     { 3, &meson_hdmi_encp_mode_480p },
0827     { 17, &meson_hdmi_encp_mode_576p },
0828     { 18, &meson_hdmi_encp_mode_576p },
0829     { 4, &meson_hdmi_encp_mode_720p60 },
0830     { 19, &meson_hdmi_encp_mode_720p50 },
0831     { 5, &meson_hdmi_encp_mode_1080i60 },
0832     { 20, &meson_hdmi_encp_mode_1080i50 },
0833     { 32, &meson_hdmi_encp_mode_1080p24 },
0834     { 33, &meson_hdmi_encp_mode_1080p50 },
0835     { 34, &meson_hdmi_encp_mode_1080p30 },
0836     { 31, &meson_hdmi_encp_mode_1080p50 },
0837     { 16, &meson_hdmi_encp_mode_1080p60 },
0838     { 93, &meson_hdmi_encp_mode_2160p24 },
0839     { 94, &meson_hdmi_encp_mode_2160p25 },
0840     { 95, &meson_hdmi_encp_mode_2160p30 },
0841     { 96, &meson_hdmi_encp_mode_2160p25 },
0842     { 97, &meson_hdmi_encp_mode_2160p30 },
0843     { 0, NULL}, /* sentinel */
0844 };
0845 
0846 static signed int to_signed(unsigned int a)
0847 {
0848     if (a <= 7)
0849         return a;
0850     else
0851         return a - 16;
0852 }
0853 
0854 static unsigned long modulo(unsigned long a, unsigned long b)
0855 {
0856     if (a >= b)
0857         return a - b;
0858     else
0859         return a;
0860 }
0861 
0862 enum drm_mode_status
0863 meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode)
0864 {
0865     if (mode->flags & ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
0866                 DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC))
0867         return MODE_BAD;
0868 
0869     if (mode->hdisplay < 640 || mode->hdisplay > 1920)
0870         return MODE_BAD_HVALUE;
0871 
0872     if (mode->vdisplay < 480 || mode->vdisplay > 1200)
0873         return MODE_BAD_VVALUE;
0874 
0875     return MODE_OK;
0876 }
0877 EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode);
0878 
0879 bool meson_venc_hdmi_supported_vic(int vic)
0880 {
0881     struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
0882 
0883     while (vmode->vic && vmode->mode) {
0884         if (vmode->vic == vic)
0885             return true;
0886         vmode++;
0887     }
0888 
0889     return false;
0890 }
0891 EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic);
0892 
0893 static void meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode,
0894                       union meson_hdmi_venc_mode *dmt_mode)
0895 {
0896     memset(dmt_mode, 0, sizeof(*dmt_mode));
0897 
0898     dmt_mode->encp.dvi_settings = 0x21;
0899     dmt_mode->encp.video_mode = 0x4040;
0900     dmt_mode->encp.video_mode_adv = 0x18;
0901     dmt_mode->encp.max_pxcnt = mode->htotal - 1;
0902     dmt_mode->encp.havon_begin = mode->htotal - mode->hsync_start;
0903     dmt_mode->encp.havon_end = dmt_mode->encp.havon_begin +
0904                    mode->hdisplay - 1;
0905     dmt_mode->encp.vavon_bline = mode->vtotal - mode->vsync_start;
0906     dmt_mode->encp.vavon_eline = dmt_mode->encp.vavon_bline +
0907                      mode->vdisplay - 1;
0908     dmt_mode->encp.hso_begin = 0;
0909     dmt_mode->encp.hso_end = mode->hsync_end - mode->hsync_start;
0910     dmt_mode->encp.vso_begin = 30;
0911     dmt_mode->encp.vso_end = 50;
0912     dmt_mode->encp.vso_bline = 0;
0913     dmt_mode->encp.vso_eline = mode->vsync_end - mode->vsync_start;
0914     dmt_mode->encp.vso_eline_present = true;
0915     dmt_mode->encp.max_lncnt = mode->vtotal - 1;
0916 }
0917 
0918 static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic)
0919 {
0920     struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
0921 
0922     while (vmode->vic && vmode->mode) {
0923         if (vmode->vic == vic)
0924             return vmode->mode;
0925         vmode++;
0926     }
0927 
0928     return NULL;
0929 }
0930 
0931 bool meson_venc_hdmi_venc_repeat(int vic)
0932 {
0933     /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
0934     if (vic == 6 || vic == 7 || /* 480i */
0935         vic == 21 || vic == 22 || /* 576i */
0936         vic == 17 || vic == 18 || /* 576p */
0937         vic == 2 || vic == 3 || /* 480p */
0938         vic == 4 || /* 720p60 */
0939         vic == 19 || /* 720p50 */
0940         vic == 5 || /* 1080i60 */
0941         vic == 20)  /* 1080i50 */
0942         return true;
0943 
0944     return false;
0945 }
0946 EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat);
0947 
0948 void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
0949                   unsigned int ycrcb_map,
0950                   bool yuv420_mode,
0951                   const struct drm_display_mode *mode)
0952 {
0953     union meson_hdmi_venc_mode *vmode = NULL;
0954     union meson_hdmi_venc_mode vmode_dmt;
0955     bool use_enci = false;
0956     bool venc_repeat = false;
0957     bool hdmi_repeat = false;
0958     unsigned int venc_hdmi_latency = 2;
0959     unsigned long total_pixels_venc = 0;
0960     unsigned long active_pixels_venc = 0;
0961     unsigned long front_porch_venc = 0;
0962     unsigned long hsync_pixels_venc = 0;
0963     unsigned long de_h_begin = 0;
0964     unsigned long de_h_end = 0;
0965     unsigned long de_v_begin_even = 0;
0966     unsigned long de_v_end_even = 0;
0967     unsigned long de_v_begin_odd = 0;
0968     unsigned long de_v_end_odd = 0;
0969     unsigned long hs_begin = 0;
0970     unsigned long hs_end = 0;
0971     unsigned long vs_adjust = 0;
0972     unsigned long vs_bline_evn = 0;
0973     unsigned long vs_eline_evn = 0;
0974     unsigned long vs_bline_odd = 0;
0975     unsigned long vs_eline_odd = 0;
0976     unsigned long vso_begin_evn = 0;
0977     unsigned long vso_begin_odd = 0;
0978     unsigned int eof_lines;
0979     unsigned int sof_lines;
0980     unsigned int vsync_lines;
0981     u32 reg;
0982 
0983     /* Use VENCI for 480i and 576i and double HDMI pixels */
0984     if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
0985         hdmi_repeat = true;
0986         use_enci = true;
0987         venc_hdmi_latency = 1;
0988     }
0989 
0990     if (meson_venc_hdmi_supported_vic(vic)) {
0991         vmode = meson_venc_hdmi_get_vic_vmode(vic);
0992         if (!vmode) {
0993             dev_err(priv->dev, "%s: Fatal Error, unsupported mode "
0994                 DRM_MODE_FMT "\n", __func__,
0995                 DRM_MODE_ARG(mode));
0996             return;
0997         }
0998     } else {
0999         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 }
1558 EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set);
1559 
1560 void 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 */
1743 unsigned 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 
1748 void 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 
1755 void 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 
1761 void 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 }