Linux Audio

Check our new training course

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