Linux Audio

Check our new training course

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