Linux Audio

Check our new training course

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