Linux Audio

Check our new training course

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