1bbbe775eSNeil Armstrong /* 2bbbe775eSNeil Armstrong * Copyright (C) 2016 BayLibre, SAS 3bbbe775eSNeil Armstrong * Author: Neil Armstrong <narmstrong@baylibre.com> 4bbbe775eSNeil Armstrong * Copyright (C) 2015 Amlogic, Inc. All rights reserved. 5bbbe775eSNeil Armstrong * 6bbbe775eSNeil Armstrong * This program is free software; you can redistribute it and/or 7bbbe775eSNeil Armstrong * modify it under the terms of the GNU General Public License as 8bbbe775eSNeil Armstrong * published by the Free Software Foundation; either version 2 of the 9bbbe775eSNeil Armstrong * License, or (at your option) any later version. 10bbbe775eSNeil Armstrong * 11bbbe775eSNeil Armstrong * This program is distributed in the hope that it will be useful, but 12bbbe775eSNeil Armstrong * WITHOUT ANY WARRANTY; without even the implied warranty of 13bbbe775eSNeil Armstrong * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14bbbe775eSNeil Armstrong * General Public License for more details. 15bbbe775eSNeil Armstrong * 16bbbe775eSNeil Armstrong * You should have received a copy of the GNU General Public License 17bbbe775eSNeil Armstrong * along with this program; if not, see <http://www.gnu.org/licenses/>. 18bbbe775eSNeil Armstrong */ 19bbbe775eSNeil Armstrong 20bbbe775eSNeil Armstrong #include <linux/kernel.h> 21bbbe775eSNeil Armstrong #include <linux/module.h> 22bbbe775eSNeil Armstrong #include <drm/drmP.h> 23bbbe775eSNeil Armstrong #include "meson_drv.h" 24bbbe775eSNeil Armstrong #include "meson_venc.h" 25bbbe775eSNeil Armstrong #include "meson_vpp.h" 26bbbe775eSNeil Armstrong #include "meson_vclk.h" 27bbbe775eSNeil Armstrong #include "meson_registers.h" 28bbbe775eSNeil Armstrong 29bbbe775eSNeil Armstrong /* 30bbbe775eSNeil Armstrong * VENC Handle the pixels encoding to the output formats. 31bbbe775eSNeil Armstrong * We handle the following encodings : 32bbbe775eSNeil Armstrong * - CVBS Encoding via the ENCI encoder and VDAC digital to analog converter 33bbbe775eSNeil Armstrong * - TMDS/HDMI Encoding via ENCI_DIV and ENCP 34bbbe775eSNeil Armstrong * - Setup of more clock rates for HDMI modes 35335e3713SNeil Armstrong * 36335e3713SNeil Armstrong * What is missing : 37bbbe775eSNeil Armstrong * - LCD Panel encoding via ENCL 38bbbe775eSNeil Armstrong * - TV Panel encoding via ENCT 39335e3713SNeil Armstrong * 40335e3713SNeil Armstrong * VENC paths : 41335e3713SNeil Armstrong * _____ _____ ____________________ 42335e3713SNeil Armstrong * vd1---| |-| | | VENC /---------|----VDAC 43335e3713SNeil Armstrong * vd2---| VIU |-| VPP |-|-----ENCI/-ENCI_DVI-|\ 44335e3713SNeil Armstrong * osd1--| |-| | | \ | X--HDMI-TX 45335e3713SNeil Armstrong * osd2--|_____|-|_____| | |\-ENCP--ENCP_DVI-|/ 46335e3713SNeil Armstrong * | | | 47335e3713SNeil Armstrong * | \--ENCL-----------|----LVDS 48335e3713SNeil Armstrong * |____________________| 49335e3713SNeil Armstrong * 50335e3713SNeil Armstrong * The ENCI is designed for PAl or NTSC encoding and can go through the VDAC 51335e3713SNeil Armstrong * directly for CVBS encoding or through the ENCI_DVI encoder for HDMI. 52335e3713SNeil Armstrong * The ENCP is designed for Progressive encoding but can also generate 53335e3713SNeil Armstrong * 1080i interlaced pixels, and was initialy desined to encode pixels for 54335e3713SNeil Armstrong * VDAC to output RGB ou YUV analog outputs. 55335e3713SNeil Armstrong * It's output is only used through the ENCP_DVI encoder for HDMI. 56335e3713SNeil Armstrong * The ENCL LVDS encoder is not implemented. 57335e3713SNeil Armstrong * 58335e3713SNeil Armstrong * The ENCI and ENCP encoders needs specially defined parameters for each 59335e3713SNeil Armstrong * supported mode and thus cannot be determined from standard video timings. 60335e3713SNeil Armstrong * 61335e3713SNeil Armstrong * The ENCI end ENCP DVI encoders are more generic and can generate any timings 62335e3713SNeil Armstrong * from the pixel data generated by ENCI or ENCP, so can use the standard video 63335e3713SNeil Armstrong * timings are source for HW parameters. 64bbbe775eSNeil Armstrong */ 65bbbe775eSNeil Armstrong 660c931a29SNeil Armstrong /* HHI Registers */ 670c931a29SNeil Armstrong #define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ 680c931a29SNeil Armstrong #define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ 690c931a29SNeil Armstrong #define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */ 700c931a29SNeil Armstrong 71bbbe775eSNeil Armstrong struct meson_cvbs_enci_mode meson_cvbs_enci_pal = { 72bbbe775eSNeil Armstrong .mode_tag = MESON_VENC_MODE_CVBS_PAL, 73bbbe775eSNeil Armstrong .hso_begin = 3, 74bbbe775eSNeil Armstrong .hso_end = 129, 75bbbe775eSNeil Armstrong .vso_even = 3, 76bbbe775eSNeil Armstrong .vso_odd = 260, 77bbbe775eSNeil Armstrong .macv_max_amp = 7, 78bbbe775eSNeil Armstrong .video_prog_mode = 0xff, 79bbbe775eSNeil Armstrong .video_mode = 0x13, 80bbbe775eSNeil Armstrong .sch_adjust = 0x28, 81bbbe775eSNeil Armstrong .yc_delay = 0x343, 82bbbe775eSNeil Armstrong .pixel_start = 251, 83bbbe775eSNeil Armstrong .pixel_end = 1691, 84bbbe775eSNeil Armstrong .top_field_line_start = 22, 85bbbe775eSNeil Armstrong .top_field_line_end = 310, 86bbbe775eSNeil Armstrong .bottom_field_line_start = 23, 87bbbe775eSNeil Armstrong .bottom_field_line_end = 311, 88bbbe775eSNeil Armstrong .video_saturation = 9, 89bbbe775eSNeil Armstrong .video_contrast = 0, 90bbbe775eSNeil Armstrong .video_brightness = 0, 91bbbe775eSNeil Armstrong .video_hue = 0, 92bbbe775eSNeil Armstrong .analog_sync_adj = 0x8080, 93bbbe775eSNeil Armstrong }; 94bbbe775eSNeil Armstrong 95bbbe775eSNeil Armstrong struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc = { 96bbbe775eSNeil Armstrong .mode_tag = MESON_VENC_MODE_CVBS_NTSC, 97bbbe775eSNeil Armstrong .hso_begin = 5, 98bbbe775eSNeil Armstrong .hso_end = 129, 99bbbe775eSNeil Armstrong .vso_even = 3, 100bbbe775eSNeil Armstrong .vso_odd = 260, 101bbbe775eSNeil Armstrong .macv_max_amp = 0xb, 102bbbe775eSNeil Armstrong .video_prog_mode = 0xf0, 103bbbe775eSNeil Armstrong .video_mode = 0x8, 104bbbe775eSNeil Armstrong .sch_adjust = 0x20, 105bbbe775eSNeil Armstrong .yc_delay = 0x333, 106bbbe775eSNeil Armstrong .pixel_start = 227, 107bbbe775eSNeil Armstrong .pixel_end = 1667, 108bbbe775eSNeil Armstrong .top_field_line_start = 18, 109bbbe775eSNeil Armstrong .top_field_line_end = 258, 110bbbe775eSNeil Armstrong .bottom_field_line_start = 19, 111bbbe775eSNeil Armstrong .bottom_field_line_end = 259, 112bbbe775eSNeil Armstrong .video_saturation = 18, 113bbbe775eSNeil Armstrong .video_contrast = 3, 114bbbe775eSNeil Armstrong .video_brightness = 0, 115bbbe775eSNeil Armstrong .video_hue = 0, 116bbbe775eSNeil Armstrong .analog_sync_adj = 0x9c00, 117bbbe775eSNeil Armstrong }; 118bbbe775eSNeil Armstrong 119335e3713SNeil Armstrong union meson_hdmi_venc_mode { 120335e3713SNeil Armstrong struct { 121335e3713SNeil Armstrong unsigned int mode_tag; 122335e3713SNeil Armstrong unsigned int hso_begin; 123335e3713SNeil Armstrong unsigned int hso_end; 124335e3713SNeil Armstrong unsigned int vso_even; 125335e3713SNeil Armstrong unsigned int vso_odd; 126335e3713SNeil Armstrong unsigned int macv_max_amp; 127335e3713SNeil Armstrong unsigned int video_prog_mode; 128335e3713SNeil Armstrong unsigned int video_mode; 129335e3713SNeil Armstrong unsigned int sch_adjust; 130335e3713SNeil Armstrong unsigned int yc_delay; 131335e3713SNeil Armstrong unsigned int pixel_start; 132335e3713SNeil Armstrong unsigned int pixel_end; 133335e3713SNeil Armstrong unsigned int top_field_line_start; 134335e3713SNeil Armstrong unsigned int top_field_line_end; 135335e3713SNeil Armstrong unsigned int bottom_field_line_start; 136335e3713SNeil Armstrong unsigned int bottom_field_line_end; 137335e3713SNeil Armstrong } enci; 138335e3713SNeil Armstrong struct { 139335e3713SNeil Armstrong unsigned int dvi_settings; 140335e3713SNeil Armstrong unsigned int video_mode; 141335e3713SNeil Armstrong unsigned int video_mode_adv; 142335e3713SNeil Armstrong unsigned int video_prog_mode; 143335e3713SNeil Armstrong bool video_prog_mode_present; 144335e3713SNeil Armstrong unsigned int video_sync_mode; 145335e3713SNeil Armstrong bool video_sync_mode_present; 146335e3713SNeil Armstrong unsigned int video_yc_dly; 147335e3713SNeil Armstrong bool video_yc_dly_present; 148335e3713SNeil Armstrong unsigned int video_rgb_ctrl; 149335e3713SNeil Armstrong bool video_rgb_ctrl_present; 150335e3713SNeil Armstrong unsigned int video_filt_ctrl; 151335e3713SNeil Armstrong bool video_filt_ctrl_present; 152335e3713SNeil Armstrong unsigned int video_ofld_voav_ofst; 153335e3713SNeil Armstrong bool video_ofld_voav_ofst_present; 154335e3713SNeil Armstrong unsigned int yfp1_htime; 155335e3713SNeil Armstrong unsigned int yfp2_htime; 156335e3713SNeil Armstrong unsigned int max_pxcnt; 157335e3713SNeil Armstrong unsigned int hspuls_begin; 158335e3713SNeil Armstrong unsigned int hspuls_end; 159335e3713SNeil Armstrong unsigned int hspuls_switch; 160335e3713SNeil Armstrong unsigned int vspuls_begin; 161335e3713SNeil Armstrong unsigned int vspuls_end; 162335e3713SNeil Armstrong unsigned int vspuls_bline; 163335e3713SNeil Armstrong unsigned int vspuls_eline; 164335e3713SNeil Armstrong unsigned int eqpuls_begin; 165335e3713SNeil Armstrong bool eqpuls_begin_present; 166335e3713SNeil Armstrong unsigned int eqpuls_end; 167335e3713SNeil Armstrong bool eqpuls_end_present; 168335e3713SNeil Armstrong unsigned int eqpuls_bline; 169335e3713SNeil Armstrong bool eqpuls_bline_present; 170335e3713SNeil Armstrong unsigned int eqpuls_eline; 171335e3713SNeil Armstrong bool eqpuls_eline_present; 172335e3713SNeil Armstrong unsigned int havon_begin; 173335e3713SNeil Armstrong unsigned int havon_end; 174335e3713SNeil Armstrong unsigned int vavon_bline; 175335e3713SNeil Armstrong unsigned int vavon_eline; 176335e3713SNeil Armstrong unsigned int hso_begin; 177335e3713SNeil Armstrong unsigned int hso_end; 178335e3713SNeil Armstrong unsigned int vso_begin; 179335e3713SNeil Armstrong unsigned int vso_end; 180335e3713SNeil Armstrong unsigned int vso_bline; 181335e3713SNeil Armstrong unsigned int vso_eline; 182335e3713SNeil Armstrong bool vso_eline_present; 183335e3713SNeil Armstrong unsigned int sy_val; 184335e3713SNeil Armstrong bool sy_val_present; 185335e3713SNeil Armstrong unsigned int sy2_val; 186335e3713SNeil Armstrong bool sy2_val_present; 187335e3713SNeil Armstrong unsigned int max_lncnt; 188335e3713SNeil Armstrong } encp; 189335e3713SNeil Armstrong }; 190335e3713SNeil Armstrong 191335e3713SNeil Armstrong union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = { 192335e3713SNeil Armstrong .enci = { 193335e3713SNeil Armstrong .hso_begin = 5, 194335e3713SNeil Armstrong .hso_end = 129, 195335e3713SNeil Armstrong .vso_even = 3, 196335e3713SNeil Armstrong .vso_odd = 260, 197335e3713SNeil Armstrong .macv_max_amp = 0x810b, 198335e3713SNeil Armstrong .video_prog_mode = 0xf0, 199335e3713SNeil Armstrong .video_mode = 0x8, 200335e3713SNeil Armstrong .sch_adjust = 0x20, 201335e3713SNeil Armstrong .yc_delay = 0, 202335e3713SNeil Armstrong .pixel_start = 227, 203335e3713SNeil Armstrong .pixel_end = 1667, 204335e3713SNeil Armstrong .top_field_line_start = 18, 205335e3713SNeil Armstrong .top_field_line_end = 258, 206335e3713SNeil Armstrong .bottom_field_line_start = 19, 207335e3713SNeil Armstrong .bottom_field_line_end = 259, 208335e3713SNeil Armstrong }, 209335e3713SNeil Armstrong }; 210335e3713SNeil Armstrong 211335e3713SNeil Armstrong union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = { 212335e3713SNeil Armstrong .enci = { 213335e3713SNeil Armstrong .hso_begin = 3, 214335e3713SNeil Armstrong .hso_end = 129, 215335e3713SNeil Armstrong .vso_even = 3, 216335e3713SNeil Armstrong .vso_odd = 260, 217335e3713SNeil Armstrong .macv_max_amp = 8107, 218335e3713SNeil Armstrong .video_prog_mode = 0xff, 219335e3713SNeil Armstrong .video_mode = 0x13, 220335e3713SNeil Armstrong .sch_adjust = 0x28, 221335e3713SNeil Armstrong .yc_delay = 0x333, 222335e3713SNeil Armstrong .pixel_start = 251, 223335e3713SNeil Armstrong .pixel_end = 1691, 224335e3713SNeil Armstrong .top_field_line_start = 22, 225335e3713SNeil Armstrong .top_field_line_end = 310, 226335e3713SNeil Armstrong .bottom_field_line_start = 23, 227335e3713SNeil Armstrong .bottom_field_line_end = 311, 228335e3713SNeil Armstrong }, 229335e3713SNeil Armstrong }; 230335e3713SNeil Armstrong 231335e3713SNeil Armstrong union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p = { 232335e3713SNeil Armstrong .encp = { 233335e3713SNeil Armstrong .dvi_settings = 0x21, 234335e3713SNeil Armstrong .video_mode = 0x4000, 235335e3713SNeil Armstrong .video_mode_adv = 0x9, 236335e3713SNeil Armstrong .video_prog_mode = 0, 237335e3713SNeil Armstrong .video_prog_mode_present = true, 238335e3713SNeil Armstrong .video_sync_mode = 7, 239335e3713SNeil Armstrong .video_sync_mode_present = true, 240335e3713SNeil Armstrong /* video_yc_dly */ 241335e3713SNeil Armstrong /* video_rgb_ctrl */ 242335e3713SNeil Armstrong .video_filt_ctrl = 0x2052, 243335e3713SNeil Armstrong .video_filt_ctrl_present = true, 244335e3713SNeil Armstrong /* video_ofld_voav_ofst */ 245335e3713SNeil Armstrong .yfp1_htime = 244, 246335e3713SNeil Armstrong .yfp2_htime = 1630, 247335e3713SNeil Armstrong .max_pxcnt = 1715, 248335e3713SNeil Armstrong .hspuls_begin = 0x22, 249335e3713SNeil Armstrong .hspuls_end = 0xa0, 250335e3713SNeil Armstrong .hspuls_switch = 88, 251335e3713SNeil Armstrong .vspuls_begin = 0, 252335e3713SNeil Armstrong .vspuls_end = 1589, 253335e3713SNeil Armstrong .vspuls_bline = 0, 254335e3713SNeil Armstrong .vspuls_eline = 5, 255335e3713SNeil Armstrong .havon_begin = 249, 256335e3713SNeil Armstrong .havon_end = 1689, 257335e3713SNeil Armstrong .vavon_bline = 42, 258335e3713SNeil Armstrong .vavon_eline = 521, 259335e3713SNeil Armstrong /* eqpuls_begin */ 260335e3713SNeil Armstrong /* eqpuls_end */ 261335e3713SNeil Armstrong /* eqpuls_bline */ 262335e3713SNeil Armstrong /* eqpuls_eline */ 263335e3713SNeil Armstrong .hso_begin = 3, 264335e3713SNeil Armstrong .hso_end = 5, 265335e3713SNeil Armstrong .vso_begin = 3, 266335e3713SNeil Armstrong .vso_end = 5, 267335e3713SNeil Armstrong .vso_bline = 0, 268335e3713SNeil Armstrong /* vso_eline */ 269335e3713SNeil Armstrong .sy_val = 8, 270335e3713SNeil Armstrong .sy_val_present = true, 271335e3713SNeil Armstrong .sy2_val = 0x1d8, 272335e3713SNeil Armstrong .sy2_val_present = true, 273335e3713SNeil Armstrong .max_lncnt = 524, 274335e3713SNeil Armstrong }, 275335e3713SNeil Armstrong }; 276335e3713SNeil Armstrong 277335e3713SNeil Armstrong union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p = { 278335e3713SNeil Armstrong .encp = { 279335e3713SNeil Armstrong .dvi_settings = 0x21, 280335e3713SNeil Armstrong .video_mode = 0x4000, 281335e3713SNeil Armstrong .video_mode_adv = 0x9, 282335e3713SNeil Armstrong .video_prog_mode = 0, 283335e3713SNeil Armstrong .video_prog_mode_present = true, 284335e3713SNeil Armstrong .video_sync_mode = 7, 285335e3713SNeil Armstrong .video_sync_mode_present = true, 286335e3713SNeil Armstrong /* video_yc_dly */ 287335e3713SNeil Armstrong /* video_rgb_ctrl */ 288335e3713SNeil Armstrong .video_filt_ctrl = 0x52, 289335e3713SNeil Armstrong .video_filt_ctrl_present = true, 290335e3713SNeil Armstrong /* video_ofld_voav_ofst */ 291335e3713SNeil Armstrong .yfp1_htime = 235, 292335e3713SNeil Armstrong .yfp2_htime = 1674, 293335e3713SNeil Armstrong .max_pxcnt = 1727, 294335e3713SNeil Armstrong .hspuls_begin = 0, 295335e3713SNeil Armstrong .hspuls_end = 0x80, 296335e3713SNeil Armstrong .hspuls_switch = 88, 297335e3713SNeil Armstrong .vspuls_begin = 0, 298335e3713SNeil Armstrong .vspuls_end = 1599, 299335e3713SNeil Armstrong .vspuls_bline = 0, 300335e3713SNeil Armstrong .vspuls_eline = 4, 301335e3713SNeil Armstrong .havon_begin = 235, 302335e3713SNeil Armstrong .havon_end = 1674, 303335e3713SNeil Armstrong .vavon_bline = 44, 304335e3713SNeil Armstrong .vavon_eline = 619, 305335e3713SNeil Armstrong /* eqpuls_begin */ 306335e3713SNeil Armstrong /* eqpuls_end */ 307335e3713SNeil Armstrong /* eqpuls_bline */ 308335e3713SNeil Armstrong /* eqpuls_eline */ 309335e3713SNeil Armstrong .hso_begin = 0x80, 310335e3713SNeil Armstrong .hso_end = 0, 311335e3713SNeil Armstrong .vso_begin = 0, 312335e3713SNeil Armstrong .vso_end = 5, 313335e3713SNeil Armstrong .vso_bline = 0, 314335e3713SNeil Armstrong /* vso_eline */ 315335e3713SNeil Armstrong .sy_val = 8, 316335e3713SNeil Armstrong .sy_val_present = true, 317335e3713SNeil Armstrong .sy2_val = 0x1d8, 318335e3713SNeil Armstrong .sy2_val_present = true, 319335e3713SNeil Armstrong .max_lncnt = 624, 320335e3713SNeil Armstrong }, 321335e3713SNeil Armstrong }; 322335e3713SNeil Armstrong 323335e3713SNeil Armstrong union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60 = { 324335e3713SNeil Armstrong .encp = { 325335e3713SNeil Armstrong .dvi_settings = 0x2029, 326335e3713SNeil Armstrong .video_mode = 0x4040, 327335e3713SNeil Armstrong .video_mode_adv = 0x19, 328335e3713SNeil Armstrong /* video_prog_mode */ 329335e3713SNeil Armstrong /* video_sync_mode */ 330335e3713SNeil Armstrong /* video_yc_dly */ 331335e3713SNeil Armstrong /* video_rgb_ctrl */ 332335e3713SNeil Armstrong /* video_filt_ctrl */ 333335e3713SNeil Armstrong /* video_ofld_voav_ofst */ 334335e3713SNeil Armstrong .yfp1_htime = 648, 335335e3713SNeil Armstrong .yfp2_htime = 3207, 336335e3713SNeil Armstrong .max_pxcnt = 3299, 337335e3713SNeil Armstrong .hspuls_begin = 80, 338335e3713SNeil Armstrong .hspuls_end = 240, 339335e3713SNeil Armstrong .hspuls_switch = 80, 340335e3713SNeil Armstrong .vspuls_begin = 688, 341335e3713SNeil Armstrong .vspuls_end = 3248, 342335e3713SNeil Armstrong .vspuls_bline = 4, 343335e3713SNeil Armstrong .vspuls_eline = 8, 344335e3713SNeil Armstrong .havon_begin = 648, 345335e3713SNeil Armstrong .havon_end = 3207, 346335e3713SNeil Armstrong .vavon_bline = 29, 347335e3713SNeil Armstrong .vavon_eline = 748, 348335e3713SNeil Armstrong /* eqpuls_begin */ 349335e3713SNeil Armstrong /* eqpuls_end */ 350335e3713SNeil Armstrong /* eqpuls_bline */ 351335e3713SNeil Armstrong /* eqpuls_eline */ 352335e3713SNeil Armstrong .hso_begin = 256, 353335e3713SNeil Armstrong .hso_end = 168, 354335e3713SNeil Armstrong .vso_begin = 168, 355335e3713SNeil Armstrong .vso_end = 256, 356335e3713SNeil Armstrong .vso_bline = 0, 357335e3713SNeil Armstrong .vso_eline = 5, 358335e3713SNeil Armstrong .vso_eline_present = true, 359335e3713SNeil Armstrong /* sy_val */ 360335e3713SNeil Armstrong /* sy2_val */ 361335e3713SNeil Armstrong .max_lncnt = 749, 362335e3713SNeil Armstrong }, 363335e3713SNeil Armstrong }; 364335e3713SNeil Armstrong 365335e3713SNeil Armstrong union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50 = { 366335e3713SNeil Armstrong .encp = { 367335e3713SNeil Armstrong .dvi_settings = 0x202d, 368335e3713SNeil Armstrong .video_mode = 0x4040, 369335e3713SNeil Armstrong .video_mode_adv = 0x19, 370335e3713SNeil Armstrong .video_prog_mode = 0x100, 371335e3713SNeil Armstrong .video_prog_mode_present = true, 372335e3713SNeil Armstrong .video_sync_mode = 0x407, 373335e3713SNeil Armstrong .video_sync_mode_present = true, 374335e3713SNeil Armstrong .video_yc_dly = 0, 375335e3713SNeil Armstrong .video_yc_dly_present = true, 376335e3713SNeil Armstrong /* video_rgb_ctrl */ 377335e3713SNeil Armstrong /* video_filt_ctrl */ 378335e3713SNeil Armstrong /* video_ofld_voav_ofst */ 379335e3713SNeil Armstrong .yfp1_htime = 648, 380335e3713SNeil Armstrong .yfp2_htime = 3207, 381335e3713SNeil Armstrong .max_pxcnt = 3959, 382335e3713SNeil Armstrong .hspuls_begin = 80, 383335e3713SNeil Armstrong .hspuls_end = 240, 384335e3713SNeil Armstrong .hspuls_switch = 80, 385335e3713SNeil Armstrong .vspuls_begin = 688, 386335e3713SNeil Armstrong .vspuls_end = 3248, 387335e3713SNeil Armstrong .vspuls_bline = 4, 388335e3713SNeil Armstrong .vspuls_eline = 8, 389335e3713SNeil Armstrong .havon_begin = 648, 390335e3713SNeil Armstrong .havon_end = 3207, 391335e3713SNeil Armstrong .vavon_bline = 29, 392335e3713SNeil Armstrong .vavon_eline = 748, 393335e3713SNeil Armstrong /* eqpuls_begin */ 394335e3713SNeil Armstrong /* eqpuls_end */ 395335e3713SNeil Armstrong /* eqpuls_bline */ 396335e3713SNeil Armstrong /* eqpuls_eline */ 397335e3713SNeil Armstrong .hso_begin = 128, 398335e3713SNeil Armstrong .hso_end = 208, 399335e3713SNeil Armstrong .vso_begin = 128, 400335e3713SNeil Armstrong .vso_end = 128, 401335e3713SNeil Armstrong .vso_bline = 0, 402335e3713SNeil Armstrong .vso_eline = 5, 403335e3713SNeil Armstrong .vso_eline_present = true, 404335e3713SNeil Armstrong /* sy_val */ 405335e3713SNeil Armstrong /* sy2_val */ 406335e3713SNeil Armstrong .max_lncnt = 749, 407335e3713SNeil Armstrong }, 408335e3713SNeil Armstrong }; 409335e3713SNeil Armstrong 410335e3713SNeil Armstrong union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60 = { 411335e3713SNeil Armstrong .encp = { 412335e3713SNeil Armstrong .dvi_settings = 0x2029, 413335e3713SNeil Armstrong .video_mode = 0x5ffc, 414335e3713SNeil Armstrong .video_mode_adv = 0x19, 415335e3713SNeil Armstrong .video_prog_mode = 0x100, 416335e3713SNeil Armstrong .video_prog_mode_present = true, 417335e3713SNeil Armstrong .video_sync_mode = 0x207, 418335e3713SNeil Armstrong .video_sync_mode_present = true, 419335e3713SNeil Armstrong /* video_yc_dly */ 420335e3713SNeil Armstrong /* video_rgb_ctrl */ 421335e3713SNeil Armstrong /* video_filt_ctrl */ 422335e3713SNeil Armstrong .video_ofld_voav_ofst = 0x11, 423335e3713SNeil Armstrong .video_ofld_voav_ofst_present = true, 424335e3713SNeil Armstrong .yfp1_htime = 516, 425335e3713SNeil Armstrong .yfp2_htime = 4355, 426335e3713SNeil Armstrong .max_pxcnt = 4399, 427335e3713SNeil Armstrong .hspuls_begin = 88, 428335e3713SNeil Armstrong .hspuls_end = 264, 429335e3713SNeil Armstrong .hspuls_switch = 88, 430335e3713SNeil Armstrong .vspuls_begin = 440, 431335e3713SNeil Armstrong .vspuls_end = 2200, 432335e3713SNeil Armstrong .vspuls_bline = 0, 433335e3713SNeil Armstrong .vspuls_eline = 4, 434335e3713SNeil Armstrong .havon_begin = 516, 435335e3713SNeil Armstrong .havon_end = 4355, 436335e3713SNeil Armstrong .vavon_bline = 20, 437335e3713SNeil Armstrong .vavon_eline = 559, 438335e3713SNeil Armstrong .eqpuls_begin = 2288, 439335e3713SNeil Armstrong .eqpuls_begin_present = true, 440335e3713SNeil Armstrong .eqpuls_end = 2464, 441335e3713SNeil Armstrong .eqpuls_end_present = true, 442335e3713SNeil Armstrong .eqpuls_bline = 0, 443335e3713SNeil Armstrong .eqpuls_bline_present = true, 444335e3713SNeil Armstrong .eqpuls_eline = 4, 445335e3713SNeil Armstrong .eqpuls_eline_present = true, 446335e3713SNeil Armstrong .hso_begin = 264, 447335e3713SNeil Armstrong .hso_end = 176, 448335e3713SNeil Armstrong .vso_begin = 88, 449335e3713SNeil Armstrong .vso_end = 88, 450335e3713SNeil Armstrong .vso_bline = 0, 451335e3713SNeil Armstrong .vso_eline = 5, 452335e3713SNeil Armstrong .vso_eline_present = true, 453335e3713SNeil Armstrong /* sy_val */ 454335e3713SNeil Armstrong /* sy2_val */ 455335e3713SNeil Armstrong .max_lncnt = 1124, 456335e3713SNeil Armstrong }, 457335e3713SNeil Armstrong }; 458335e3713SNeil Armstrong 459335e3713SNeil Armstrong union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50 = { 460335e3713SNeil Armstrong .encp = { 461335e3713SNeil Armstrong .dvi_settings = 0x202d, 462335e3713SNeil Armstrong .video_mode = 0x5ffc, 463335e3713SNeil Armstrong .video_mode_adv = 0x19, 464335e3713SNeil Armstrong .video_prog_mode = 0x100, 465335e3713SNeil Armstrong .video_prog_mode_present = true, 466335e3713SNeil Armstrong .video_sync_mode = 0x7, 467335e3713SNeil Armstrong .video_sync_mode_present = true, 468335e3713SNeil Armstrong /* video_yc_dly */ 469335e3713SNeil Armstrong /* video_rgb_ctrl */ 470335e3713SNeil Armstrong /* video_filt_ctrl */ 471335e3713SNeil Armstrong .video_ofld_voav_ofst = 0x11, 472335e3713SNeil Armstrong .video_ofld_voav_ofst_present = true, 473335e3713SNeil Armstrong .yfp1_htime = 526, 474335e3713SNeil Armstrong .yfp2_htime = 4365, 475335e3713SNeil Armstrong .max_pxcnt = 5279, 476335e3713SNeil Armstrong .hspuls_begin = 88, 477335e3713SNeil Armstrong .hspuls_end = 264, 478335e3713SNeil Armstrong .hspuls_switch = 88, 479335e3713SNeil Armstrong .vspuls_begin = 440, 480335e3713SNeil Armstrong .vspuls_end = 2200, 481335e3713SNeil Armstrong .vspuls_bline = 0, 482335e3713SNeil Armstrong .vspuls_eline = 4, 483335e3713SNeil Armstrong .havon_begin = 526, 484335e3713SNeil Armstrong .havon_end = 4365, 485335e3713SNeil Armstrong .vavon_bline = 20, 486335e3713SNeil Armstrong .vavon_eline = 559, 487335e3713SNeil Armstrong .eqpuls_begin = 2288, 488335e3713SNeil Armstrong .eqpuls_begin_present = true, 489335e3713SNeil Armstrong .eqpuls_end = 2464, 490335e3713SNeil Armstrong .eqpuls_end_present = true, 491335e3713SNeil Armstrong .eqpuls_bline = 0, 492335e3713SNeil Armstrong .eqpuls_bline_present = true, 493335e3713SNeil Armstrong .eqpuls_eline = 4, 494335e3713SNeil Armstrong .eqpuls_eline_present = true, 495335e3713SNeil Armstrong .hso_begin = 142, 496335e3713SNeil Armstrong .hso_end = 230, 497335e3713SNeil Armstrong .vso_begin = 142, 498335e3713SNeil Armstrong .vso_end = 142, 499335e3713SNeil Armstrong .vso_bline = 0, 500335e3713SNeil Armstrong .vso_eline = 5, 501335e3713SNeil Armstrong .vso_eline_present = true, 502335e3713SNeil Armstrong /* sy_val */ 503335e3713SNeil Armstrong /* sy2_val */ 504335e3713SNeil Armstrong .max_lncnt = 1124, 505335e3713SNeil Armstrong }, 506335e3713SNeil Armstrong }; 507335e3713SNeil Armstrong 508335e3713SNeil Armstrong union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24 = { 509335e3713SNeil Armstrong .encp = { 510335e3713SNeil Armstrong .dvi_settings = 0xd, 511335e3713SNeil Armstrong .video_mode = 0x4040, 512335e3713SNeil Armstrong .video_mode_adv = 0x18, 513335e3713SNeil Armstrong .video_prog_mode = 0x100, 514335e3713SNeil Armstrong .video_prog_mode_present = true, 515335e3713SNeil Armstrong .video_sync_mode = 0x7, 516335e3713SNeil Armstrong .video_sync_mode_present = true, 517335e3713SNeil Armstrong .video_yc_dly = 0, 518335e3713SNeil Armstrong .video_yc_dly_present = true, 519335e3713SNeil Armstrong .video_rgb_ctrl = 2, 520335e3713SNeil Armstrong .video_rgb_ctrl_present = true, 521335e3713SNeil Armstrong .video_filt_ctrl = 0x1052, 522335e3713SNeil Armstrong .video_filt_ctrl_present = true, 523335e3713SNeil Armstrong /* video_ofld_voav_ofst */ 524335e3713SNeil Armstrong .yfp1_htime = 271, 525335e3713SNeil Armstrong .yfp2_htime = 2190, 526335e3713SNeil Armstrong .max_pxcnt = 2749, 527335e3713SNeil Armstrong .hspuls_begin = 44, 528335e3713SNeil Armstrong .hspuls_end = 132, 529335e3713SNeil Armstrong .hspuls_switch = 44, 530335e3713SNeil Armstrong .vspuls_begin = 220, 531335e3713SNeil Armstrong .vspuls_end = 2140, 532335e3713SNeil Armstrong .vspuls_bline = 0, 533335e3713SNeil Armstrong .vspuls_eline = 4, 534335e3713SNeil Armstrong .havon_begin = 271, 535335e3713SNeil Armstrong .havon_end = 2190, 536335e3713SNeil Armstrong .vavon_bline = 41, 537335e3713SNeil Armstrong .vavon_eline = 1120, 538335e3713SNeil Armstrong /* eqpuls_begin */ 539335e3713SNeil Armstrong /* eqpuls_end */ 540335e3713SNeil Armstrong .eqpuls_bline = 0, 541335e3713SNeil Armstrong .eqpuls_bline_present = true, 542335e3713SNeil Armstrong .eqpuls_eline = 4, 543335e3713SNeil Armstrong .eqpuls_eline_present = true, 544335e3713SNeil Armstrong .hso_begin = 79, 545335e3713SNeil Armstrong .hso_end = 123, 546335e3713SNeil Armstrong .vso_begin = 79, 547335e3713SNeil Armstrong .vso_end = 79, 548335e3713SNeil Armstrong .vso_bline = 0, 549335e3713SNeil Armstrong .vso_eline = 5, 550335e3713SNeil Armstrong .vso_eline_present = true, 551335e3713SNeil Armstrong /* sy_val */ 552335e3713SNeil Armstrong /* sy2_val */ 553335e3713SNeil Armstrong .max_lncnt = 1124, 554335e3713SNeil Armstrong }, 555335e3713SNeil Armstrong }; 556335e3713SNeil Armstrong 557335e3713SNeil Armstrong union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30 = { 558335e3713SNeil Armstrong .encp = { 559335e3713SNeil Armstrong .dvi_settings = 0x1, 560335e3713SNeil Armstrong .video_mode = 0x4040, 561335e3713SNeil Armstrong .video_mode_adv = 0x18, 562335e3713SNeil Armstrong .video_prog_mode = 0x100, 563335e3713SNeil Armstrong .video_prog_mode_present = true, 564335e3713SNeil Armstrong /* video_sync_mode */ 565335e3713SNeil Armstrong /* video_yc_dly */ 566335e3713SNeil Armstrong /* video_rgb_ctrl */ 567335e3713SNeil Armstrong .video_filt_ctrl = 0x1052, 568335e3713SNeil Armstrong .video_filt_ctrl_present = true, 569335e3713SNeil Armstrong /* video_ofld_voav_ofst */ 570335e3713SNeil Armstrong .yfp1_htime = 140, 571335e3713SNeil Armstrong .yfp2_htime = 2060, 572335e3713SNeil Armstrong .max_pxcnt = 2199, 573335e3713SNeil Armstrong .hspuls_begin = 2156, 574335e3713SNeil Armstrong .hspuls_end = 44, 575335e3713SNeil Armstrong .hspuls_switch = 44, 576335e3713SNeil Armstrong .vspuls_begin = 140, 577335e3713SNeil Armstrong .vspuls_end = 2059, 578335e3713SNeil Armstrong .vspuls_bline = 0, 579335e3713SNeil Armstrong .vspuls_eline = 4, 580335e3713SNeil Armstrong .havon_begin = 148, 581335e3713SNeil Armstrong .havon_end = 2067, 582335e3713SNeil Armstrong .vavon_bline = 41, 583335e3713SNeil Armstrong .vavon_eline = 1120, 584335e3713SNeil Armstrong /* eqpuls_begin */ 585335e3713SNeil Armstrong /* eqpuls_end */ 586335e3713SNeil Armstrong /* eqpuls_bline */ 587335e3713SNeil Armstrong /* eqpuls_eline */ 588335e3713SNeil Armstrong .hso_begin = 44, 589335e3713SNeil Armstrong .hso_end = 2156, 590335e3713SNeil Armstrong .vso_begin = 2100, 591335e3713SNeil Armstrong .vso_end = 2164, 592335e3713SNeil Armstrong .vso_bline = 0, 593335e3713SNeil Armstrong .vso_eline = 5, 594335e3713SNeil Armstrong .vso_eline_present = true, 595335e3713SNeil Armstrong /* sy_val */ 596335e3713SNeil Armstrong /* sy2_val */ 597335e3713SNeil Armstrong .max_lncnt = 1124, 598335e3713SNeil Armstrong }, 599335e3713SNeil Armstrong }; 600335e3713SNeil Armstrong 601335e3713SNeil Armstrong union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50 = { 602335e3713SNeil Armstrong .encp = { 603335e3713SNeil Armstrong .dvi_settings = 0xd, 604335e3713SNeil Armstrong .video_mode = 0x4040, 605335e3713SNeil Armstrong .video_mode_adv = 0x18, 606335e3713SNeil Armstrong .video_prog_mode = 0x100, 607335e3713SNeil Armstrong .video_prog_mode_present = true, 608335e3713SNeil Armstrong .video_sync_mode = 0x7, 609335e3713SNeil Armstrong .video_sync_mode_present = true, 610335e3713SNeil Armstrong .video_yc_dly = 0, 611335e3713SNeil Armstrong .video_yc_dly_present = true, 612335e3713SNeil Armstrong .video_rgb_ctrl = 2, 613335e3713SNeil Armstrong .video_rgb_ctrl_present = true, 614335e3713SNeil Armstrong /* video_filt_ctrl */ 615335e3713SNeil Armstrong /* video_ofld_voav_ofst */ 616335e3713SNeil Armstrong .yfp1_htime = 271, 617335e3713SNeil Armstrong .yfp2_htime = 2190, 618335e3713SNeil Armstrong .max_pxcnt = 2639, 619335e3713SNeil Armstrong .hspuls_begin = 44, 620335e3713SNeil Armstrong .hspuls_end = 132, 621335e3713SNeil Armstrong .hspuls_switch = 44, 622335e3713SNeil Armstrong .vspuls_begin = 220, 623335e3713SNeil Armstrong .vspuls_end = 2140, 624335e3713SNeil Armstrong .vspuls_bline = 0, 625335e3713SNeil Armstrong .vspuls_eline = 4, 626335e3713SNeil Armstrong .havon_begin = 271, 627335e3713SNeil Armstrong .havon_end = 2190, 628335e3713SNeil Armstrong .vavon_bline = 41, 629335e3713SNeil Armstrong .vavon_eline = 1120, 630335e3713SNeil Armstrong /* eqpuls_begin */ 631335e3713SNeil Armstrong /* eqpuls_end */ 632335e3713SNeil Armstrong .eqpuls_bline = 0, 633335e3713SNeil Armstrong .eqpuls_bline_present = true, 634335e3713SNeil Armstrong .eqpuls_eline = 4, 635335e3713SNeil Armstrong .eqpuls_eline_present = true, 636335e3713SNeil Armstrong .hso_begin = 79, 637335e3713SNeil Armstrong .hso_end = 123, 638335e3713SNeil Armstrong .vso_begin = 79, 639335e3713SNeil Armstrong .vso_end = 79, 640335e3713SNeil Armstrong .vso_bline = 0, 641335e3713SNeil Armstrong .vso_eline = 5, 642335e3713SNeil Armstrong .vso_eline_present = true, 643335e3713SNeil Armstrong /* sy_val */ 644335e3713SNeil Armstrong /* sy2_val */ 645335e3713SNeil Armstrong .max_lncnt = 1124, 646335e3713SNeil Armstrong }, 647335e3713SNeil Armstrong }; 648335e3713SNeil Armstrong 649335e3713SNeil Armstrong union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = { 650335e3713SNeil Armstrong .encp = { 651335e3713SNeil Armstrong .dvi_settings = 0x1, 652335e3713SNeil Armstrong .video_mode = 0x4040, 653335e3713SNeil Armstrong .video_mode_adv = 0x18, 654335e3713SNeil Armstrong .video_prog_mode = 0x100, 655335e3713SNeil Armstrong .video_prog_mode_present = true, 656335e3713SNeil Armstrong /* video_sync_mode */ 657335e3713SNeil Armstrong /* video_yc_dly */ 658335e3713SNeil Armstrong /* video_rgb_ctrl */ 659335e3713SNeil Armstrong .video_filt_ctrl = 0x1052, 660335e3713SNeil Armstrong .video_filt_ctrl_present = true, 661335e3713SNeil Armstrong /* video_ofld_voav_ofst */ 662335e3713SNeil Armstrong .yfp1_htime = 140, 663335e3713SNeil Armstrong .yfp2_htime = 2060, 664335e3713SNeil Armstrong .max_pxcnt = 2199, 665335e3713SNeil Armstrong .hspuls_begin = 2156, 666335e3713SNeil Armstrong .hspuls_end = 44, 667335e3713SNeil Armstrong .hspuls_switch = 44, 668335e3713SNeil Armstrong .vspuls_begin = 140, 669335e3713SNeil Armstrong .vspuls_end = 2059, 670335e3713SNeil Armstrong .vspuls_bline = 0, 671335e3713SNeil Armstrong .vspuls_eline = 4, 672335e3713SNeil Armstrong .havon_begin = 148, 673335e3713SNeil Armstrong .havon_end = 2067, 674335e3713SNeil Armstrong .vavon_bline = 41, 675335e3713SNeil Armstrong .vavon_eline = 1120, 676335e3713SNeil Armstrong /* eqpuls_begin */ 677335e3713SNeil Armstrong /* eqpuls_end */ 678335e3713SNeil Armstrong /* eqpuls_bline */ 679335e3713SNeil Armstrong /* eqpuls_eline */ 680335e3713SNeil Armstrong .hso_begin = 44, 681335e3713SNeil Armstrong .hso_end = 2156, 682335e3713SNeil Armstrong .vso_begin = 2100, 683335e3713SNeil Armstrong .vso_end = 2164, 684335e3713SNeil Armstrong .vso_bline = 0, 685335e3713SNeil Armstrong .vso_eline = 5, 686335e3713SNeil Armstrong .vso_eline_present = true, 687335e3713SNeil Armstrong /* sy_val */ 688335e3713SNeil Armstrong /* sy2_val */ 689335e3713SNeil Armstrong .max_lncnt = 1124, 690335e3713SNeil Armstrong }, 691335e3713SNeil Armstrong }; 692335e3713SNeil Armstrong 693335e3713SNeil Armstrong struct meson_hdmi_venc_vic_mode { 694335e3713SNeil Armstrong unsigned int vic; 695335e3713SNeil Armstrong union meson_hdmi_venc_mode *mode; 696335e3713SNeil Armstrong } meson_hdmi_venc_vic_modes[] = { 697335e3713SNeil Armstrong { 6, &meson_hdmi_enci_mode_480i }, 698335e3713SNeil Armstrong { 7, &meson_hdmi_enci_mode_480i }, 699335e3713SNeil Armstrong { 21, &meson_hdmi_enci_mode_576i }, 700335e3713SNeil Armstrong { 22, &meson_hdmi_enci_mode_576i }, 701335e3713SNeil Armstrong { 2, &meson_hdmi_encp_mode_480p }, 702335e3713SNeil Armstrong { 3, &meson_hdmi_encp_mode_480p }, 703335e3713SNeil Armstrong { 17, &meson_hdmi_encp_mode_576p }, 704335e3713SNeil Armstrong { 18, &meson_hdmi_encp_mode_576p }, 705335e3713SNeil Armstrong { 4, &meson_hdmi_encp_mode_720p60 }, 706335e3713SNeil Armstrong { 19, &meson_hdmi_encp_mode_720p50 }, 707335e3713SNeil Armstrong { 5, &meson_hdmi_encp_mode_1080i60 }, 708335e3713SNeil Armstrong { 20, &meson_hdmi_encp_mode_1080i50 }, 709335e3713SNeil Armstrong { 32, &meson_hdmi_encp_mode_1080p24 }, 710335e3713SNeil Armstrong { 34, &meson_hdmi_encp_mode_1080p30 }, 711335e3713SNeil Armstrong { 31, &meson_hdmi_encp_mode_1080p50 }, 712335e3713SNeil Armstrong { 16, &meson_hdmi_encp_mode_1080p60 }, 713335e3713SNeil Armstrong { 0, NULL}, /* sentinel */ 714335e3713SNeil Armstrong }; 715335e3713SNeil Armstrong 716335e3713SNeil Armstrong static signed int to_signed(unsigned int a) 717335e3713SNeil Armstrong { 718335e3713SNeil Armstrong if (a <= 7) 719335e3713SNeil Armstrong return a; 720335e3713SNeil Armstrong else 721335e3713SNeil Armstrong return a - 16; 722335e3713SNeil Armstrong } 723335e3713SNeil Armstrong 724335e3713SNeil Armstrong static unsigned long modulo(unsigned long a, unsigned long b) 725335e3713SNeil Armstrong { 726335e3713SNeil Armstrong if (a >= b) 727335e3713SNeil Armstrong return a - b; 728335e3713SNeil Armstrong else 729335e3713SNeil Armstrong return a; 730335e3713SNeil Armstrong } 731335e3713SNeil Armstrong 732335e3713SNeil Armstrong bool meson_venc_hdmi_supported_vic(int vic) 733335e3713SNeil Armstrong { 734335e3713SNeil Armstrong struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes; 735335e3713SNeil Armstrong 736335e3713SNeil Armstrong while (vmode->vic && vmode->mode) { 737335e3713SNeil Armstrong if (vmode->vic == vic) 738335e3713SNeil Armstrong return true; 739335e3713SNeil Armstrong vmode++; 740335e3713SNeil Armstrong } 741335e3713SNeil Armstrong 742335e3713SNeil Armstrong return false; 743335e3713SNeil Armstrong } 744335e3713SNeil Armstrong EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic); 745335e3713SNeil Armstrong 746335e3713SNeil Armstrong static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic) 747335e3713SNeil Armstrong { 748335e3713SNeil Armstrong struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes; 749335e3713SNeil Armstrong 750335e3713SNeil Armstrong while (vmode->vic && vmode->mode) { 751335e3713SNeil Armstrong if (vmode->vic == vic) 752335e3713SNeil Armstrong return vmode->mode; 753335e3713SNeil Armstrong vmode++; 754335e3713SNeil Armstrong } 755335e3713SNeil Armstrong 756335e3713SNeil Armstrong return NULL; 757335e3713SNeil Armstrong } 758335e3713SNeil Armstrong 759335e3713SNeil Armstrong bool meson_venc_hdmi_venc_repeat(int vic) 760335e3713SNeil Armstrong { 761335e3713SNeil Armstrong /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */ 762335e3713SNeil Armstrong if (vic == 6 || vic == 7 || /* 480i */ 763335e3713SNeil Armstrong vic == 21 || vic == 22 || /* 576i */ 764335e3713SNeil Armstrong vic == 17 || vic == 18 || /* 576p */ 765335e3713SNeil Armstrong vic == 2 || vic == 3 || /* 480p */ 766335e3713SNeil Armstrong vic == 4 || /* 720p60 */ 767335e3713SNeil Armstrong vic == 19 || /* 720p50 */ 768335e3713SNeil Armstrong vic == 5 || /* 1080i60 */ 769335e3713SNeil Armstrong vic == 20) /* 1080i50 */ 770335e3713SNeil Armstrong return true; 771335e3713SNeil Armstrong 772335e3713SNeil Armstrong return false; 773335e3713SNeil Armstrong } 774335e3713SNeil Armstrong EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat); 775335e3713SNeil Armstrong 776335e3713SNeil Armstrong void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, 777335e3713SNeil Armstrong struct drm_display_mode *mode) 778335e3713SNeil Armstrong { 779335e3713SNeil Armstrong union meson_hdmi_venc_mode *vmode = NULL; 780335e3713SNeil Armstrong bool use_enci = false; 781335e3713SNeil Armstrong bool venc_repeat = false; 782335e3713SNeil Armstrong bool hdmi_repeat = false; 783335e3713SNeil Armstrong unsigned int venc_hdmi_latency = 2; 784335e3713SNeil Armstrong unsigned long total_pixels_venc = 0; 785335e3713SNeil Armstrong unsigned long active_pixels_venc = 0; 786335e3713SNeil Armstrong unsigned long front_porch_venc = 0; 787335e3713SNeil Armstrong unsigned long hsync_pixels_venc = 0; 788335e3713SNeil Armstrong unsigned long de_h_begin = 0; 789335e3713SNeil Armstrong unsigned long de_h_end = 0; 790335e3713SNeil Armstrong unsigned long de_v_begin_even = 0; 791335e3713SNeil Armstrong unsigned long de_v_end_even = 0; 792335e3713SNeil Armstrong unsigned long de_v_begin_odd = 0; 793335e3713SNeil Armstrong unsigned long de_v_end_odd = 0; 794335e3713SNeil Armstrong unsigned long hs_begin = 0; 795335e3713SNeil Armstrong unsigned long hs_end = 0; 796335e3713SNeil Armstrong unsigned long vs_adjust = 0; 797335e3713SNeil Armstrong unsigned long vs_bline_evn = 0; 798335e3713SNeil Armstrong unsigned long vs_eline_evn = 0; 799335e3713SNeil Armstrong unsigned long vs_bline_odd = 0; 800335e3713SNeil Armstrong unsigned long vs_eline_odd = 0; 801335e3713SNeil Armstrong unsigned long vso_begin_evn = 0; 802335e3713SNeil Armstrong unsigned long vso_begin_odd = 0; 803335e3713SNeil Armstrong unsigned int eof_lines; 804335e3713SNeil Armstrong unsigned int sof_lines; 805335e3713SNeil Armstrong unsigned int vsync_lines; 806335e3713SNeil Armstrong 807335e3713SNeil Armstrong vmode = meson_venc_hdmi_get_vic_vmode(vic); 808335e3713SNeil Armstrong if (!vmode) { 809335e3713SNeil Armstrong dev_err(priv->dev, "%s: Fatal Error, unsupported vic %d\n", 810335e3713SNeil Armstrong __func__, vic); 811335e3713SNeil Armstrong return; 812335e3713SNeil Armstrong } 813335e3713SNeil Armstrong 814335e3713SNeil Armstrong /* Use VENCI for 480i and 576i and double HDMI pixels */ 815335e3713SNeil Armstrong if (mode->flags & DRM_MODE_FLAG_DBLCLK) { 816335e3713SNeil Armstrong hdmi_repeat = true; 817335e3713SNeil Armstrong use_enci = true; 818335e3713SNeil Armstrong venc_hdmi_latency = 1; 819335e3713SNeil Armstrong } 820335e3713SNeil Armstrong 821335e3713SNeil Armstrong /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */ 822335e3713SNeil Armstrong if (meson_venc_hdmi_venc_repeat(vic)) 823335e3713SNeil Armstrong venc_repeat = true; 824335e3713SNeil Armstrong 825335e3713SNeil Armstrong eof_lines = mode->vsync_start - mode->vdisplay; 826335e3713SNeil Armstrong if (mode->flags & DRM_MODE_FLAG_INTERLACE) 827335e3713SNeil Armstrong eof_lines /= 2; 828335e3713SNeil Armstrong sof_lines = mode->vtotal - mode->vsync_end; 829335e3713SNeil Armstrong if (mode->flags & DRM_MODE_FLAG_INTERLACE) 830335e3713SNeil Armstrong sof_lines /= 2; 831335e3713SNeil Armstrong vsync_lines = mode->vsync_end - mode->vsync_start; 832335e3713SNeil Armstrong if (mode->flags & DRM_MODE_FLAG_INTERLACE) 833335e3713SNeil Armstrong vsync_lines /= 2; 834335e3713SNeil Armstrong 835335e3713SNeil Armstrong total_pixels_venc = mode->htotal; 836335e3713SNeil Armstrong if (hdmi_repeat) 837335e3713SNeil Armstrong total_pixels_venc /= 2; 838335e3713SNeil Armstrong if (venc_repeat) 839335e3713SNeil Armstrong total_pixels_venc *= 2; 840335e3713SNeil Armstrong 841335e3713SNeil Armstrong active_pixels_venc = mode->hdisplay; 842335e3713SNeil Armstrong if (hdmi_repeat) 843335e3713SNeil Armstrong active_pixels_venc /= 2; 844335e3713SNeil Armstrong if (venc_repeat) 845335e3713SNeil Armstrong active_pixels_venc *= 2; 846335e3713SNeil Armstrong 847335e3713SNeil Armstrong front_porch_venc = (mode->hsync_start - mode->hdisplay); 848335e3713SNeil Armstrong if (hdmi_repeat) 849335e3713SNeil Armstrong front_porch_venc /= 2; 850335e3713SNeil Armstrong if (venc_repeat) 851335e3713SNeil Armstrong front_porch_venc *= 2; 852335e3713SNeil Armstrong 853335e3713SNeil Armstrong hsync_pixels_venc = (mode->hsync_end - mode->hsync_start); 854335e3713SNeil Armstrong if (hdmi_repeat) 855335e3713SNeil Armstrong hsync_pixels_venc /= 2; 856335e3713SNeil Armstrong if (venc_repeat) 857335e3713SNeil Armstrong hsync_pixels_venc *= 2; 858335e3713SNeil Armstrong 859335e3713SNeil Armstrong /* Disable VDACs */ 860335e3713SNeil Armstrong writel_bits_relaxed(0x1f, 0x1f, 861335e3713SNeil Armstrong priv->io_base + _REG(VENC_VDAC_SETTING)); 862335e3713SNeil Armstrong 863335e3713SNeil Armstrong writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); 864335e3713SNeil Armstrong writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); 865335e3713SNeil Armstrong 866335e3713SNeil Armstrong if (use_enci) { 867335e3713SNeil Armstrong unsigned int lines_f0; 868335e3713SNeil Armstrong unsigned int lines_f1; 869335e3713SNeil Armstrong 870335e3713SNeil Armstrong /* CVBS Filter settings */ 871335e3713SNeil Armstrong writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL)); 872335e3713SNeil Armstrong writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2)); 873335e3713SNeil Armstrong 874335e3713SNeil Armstrong /* Digital Video Select : Interlace, clk27 clk, external */ 875335e3713SNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING)); 876335e3713SNeil Armstrong 877335e3713SNeil Armstrong /* Reset Video Mode */ 878335e3713SNeil Armstrong writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE)); 879335e3713SNeil Armstrong writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); 880335e3713SNeil Armstrong 881335e3713SNeil Armstrong /* Horizontal sync signal output */ 882335e3713SNeil Armstrong writel_relaxed(vmode->enci.hso_begin, 883335e3713SNeil Armstrong priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN)); 884335e3713SNeil Armstrong writel_relaxed(vmode->enci.hso_end, 885335e3713SNeil Armstrong priv->io_base + _REG(ENCI_SYNC_HSO_END)); 886335e3713SNeil Armstrong 887335e3713SNeil Armstrong /* Vertical Sync lines */ 888335e3713SNeil Armstrong writel_relaxed(vmode->enci.vso_even, 889335e3713SNeil Armstrong priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN)); 890335e3713SNeil Armstrong writel_relaxed(vmode->enci.vso_odd, 891335e3713SNeil Armstrong priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN)); 892335e3713SNeil Armstrong 893335e3713SNeil Armstrong /* Macrovision max amplitude change */ 894335e3713SNeil Armstrong writel_relaxed(vmode->enci.macv_max_amp, 895335e3713SNeil Armstrong priv->io_base + _REG(ENCI_MACV_MAX_AMP)); 896335e3713SNeil Armstrong 897335e3713SNeil Armstrong /* Video mode */ 898335e3713SNeil Armstrong writel_relaxed(vmode->enci.video_prog_mode, 899335e3713SNeil Armstrong priv->io_base + _REG(VENC_VIDEO_PROG_MODE)); 900335e3713SNeil Armstrong writel_relaxed(vmode->enci.video_mode, 901335e3713SNeil Armstrong priv->io_base + _REG(ENCI_VIDEO_MODE)); 902335e3713SNeil Armstrong 903335e3713SNeil Armstrong /* Advanced Video Mode : 904335e3713SNeil Armstrong * Demux shifting 0x2 905335e3713SNeil Armstrong * Blank line end at line17/22 906335e3713SNeil Armstrong * High bandwidth Luma Filter 907335e3713SNeil Armstrong * Low bandwidth Chroma Filter 908335e3713SNeil Armstrong * Bypass luma low pass filter 909335e3713SNeil Armstrong * No macrovision on CSYNC 910335e3713SNeil Armstrong */ 911335e3713SNeil Armstrong writel_relaxed(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); 912335e3713SNeil Armstrong 913335e3713SNeil Armstrong writel(vmode->enci.sch_adjust, 914335e3713SNeil Armstrong priv->io_base + _REG(ENCI_VIDEO_SCH)); 915335e3713SNeil Armstrong 916335e3713SNeil Armstrong /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */ 917335e3713SNeil Armstrong writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE)); 918335e3713SNeil Armstrong 919335e3713SNeil Armstrong if (vmode->enci.yc_delay) 920335e3713SNeil Armstrong writel_relaxed(vmode->enci.yc_delay, 921335e3713SNeil Armstrong priv->io_base + _REG(ENCI_YC_DELAY)); 922335e3713SNeil Armstrong 923335e3713SNeil Armstrong 924335e3713SNeil Armstrong /* UNreset Interlaced TV Encoder */ 925335e3713SNeil Armstrong writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST)); 926335e3713SNeil Armstrong 927335e3713SNeil Armstrong /* Enable Vfifo2vd, Y_Cb_Y_Cr select */ 928335e3713SNeil Armstrong writel_relaxed(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); 929335e3713SNeil Armstrong 930335e3713SNeil Armstrong /* Timings */ 931335e3713SNeil Armstrong writel_relaxed(vmode->enci.pixel_start, 932335e3713SNeil Armstrong priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START)); 933335e3713SNeil Armstrong writel_relaxed(vmode->enci.pixel_end, 934335e3713SNeil Armstrong priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END)); 935335e3713SNeil Armstrong 936335e3713SNeil Armstrong writel_relaxed(vmode->enci.top_field_line_start, 937335e3713SNeil Armstrong priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START)); 938335e3713SNeil Armstrong writel_relaxed(vmode->enci.top_field_line_end, 939335e3713SNeil Armstrong priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END)); 940335e3713SNeil Armstrong 941335e3713SNeil Armstrong writel_relaxed(vmode->enci.bottom_field_line_start, 942335e3713SNeil Armstrong priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START)); 943335e3713SNeil Armstrong writel_relaxed(vmode->enci.bottom_field_line_end, 944335e3713SNeil Armstrong priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END)); 945335e3713SNeil Armstrong 946335e3713SNeil Armstrong /* Select ENCI for VIU */ 947335e3713SNeil Armstrong meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI); 948335e3713SNeil Armstrong 949335e3713SNeil Armstrong /* Interlace video enable */ 950335e3713SNeil Armstrong writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); 951335e3713SNeil Armstrong 952335e3713SNeil Armstrong lines_f0 = mode->vtotal >> 1; 953335e3713SNeil Armstrong lines_f1 = lines_f0 + 1; 954335e3713SNeil Armstrong 955335e3713SNeil Armstrong de_h_begin = modulo(readl_relaxed(priv->io_base + 956335e3713SNeil Armstrong _REG(ENCI_VFIFO2VD_PIXEL_START)) 957335e3713SNeil Armstrong + venc_hdmi_latency, 958335e3713SNeil Armstrong total_pixels_venc); 959335e3713SNeil Armstrong de_h_end = modulo(de_h_begin + active_pixels_venc, 960335e3713SNeil Armstrong total_pixels_venc); 961335e3713SNeil Armstrong 962335e3713SNeil Armstrong writel_relaxed(de_h_begin, 963335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DE_H_BEGIN)); 964335e3713SNeil Armstrong writel_relaxed(de_h_end, 965335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DE_H_END)); 966335e3713SNeil Armstrong 967335e3713SNeil Armstrong de_v_begin_even = readl_relaxed(priv->io_base + 968335e3713SNeil Armstrong _REG(ENCI_VFIFO2VD_LINE_TOP_START)); 969335e3713SNeil Armstrong de_v_end_even = de_v_begin_even + mode->vdisplay; 970335e3713SNeil Armstrong de_v_begin_odd = readl_relaxed(priv->io_base + 971335e3713SNeil Armstrong _REG(ENCI_VFIFO2VD_LINE_BOT_START)); 972335e3713SNeil Armstrong de_v_end_odd = de_v_begin_odd + mode->vdisplay; 973335e3713SNeil Armstrong 974335e3713SNeil Armstrong writel_relaxed(de_v_begin_even, 975335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DE_V_BEGIN_EVEN)); 976335e3713SNeil Armstrong writel_relaxed(de_v_end_even, 977335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DE_V_END_EVEN)); 978335e3713SNeil Armstrong writel_relaxed(de_v_begin_odd, 979335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DE_V_BEGIN_ODD)); 980335e3713SNeil Armstrong writel_relaxed(de_v_end_odd, 981335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DE_V_END_ODD)); 982335e3713SNeil Armstrong 983335e3713SNeil Armstrong /* Program Hsync timing */ 984335e3713SNeil Armstrong hs_begin = de_h_end + front_porch_venc; 985335e3713SNeil Armstrong if (de_h_end + front_porch_venc >= total_pixels_venc) { 986335e3713SNeil Armstrong hs_begin -= total_pixels_venc; 987335e3713SNeil Armstrong vs_adjust = 1; 988335e3713SNeil Armstrong } else { 989335e3713SNeil Armstrong hs_begin = de_h_end + front_porch_venc; 990335e3713SNeil Armstrong vs_adjust = 0; 991335e3713SNeil Armstrong } 992335e3713SNeil Armstrong 993335e3713SNeil Armstrong hs_end = modulo(hs_begin + hsync_pixels_venc, 994335e3713SNeil Armstrong total_pixels_venc); 995335e3713SNeil Armstrong writel_relaxed(hs_begin, 996335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_HSO_BEGIN)); 997335e3713SNeil Armstrong writel_relaxed(hs_end, 998335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_HSO_END)); 999335e3713SNeil Armstrong 1000335e3713SNeil Armstrong /* Program Vsync timing for even field */ 1001335e3713SNeil Armstrong if (((de_v_end_odd - 1) + eof_lines + vs_adjust) >= lines_f1) { 1002335e3713SNeil Armstrong vs_bline_evn = (de_v_end_odd - 1) 1003335e3713SNeil Armstrong + eof_lines 1004335e3713SNeil Armstrong + vs_adjust 1005335e3713SNeil Armstrong - lines_f1; 1006335e3713SNeil Armstrong vs_eline_evn = vs_bline_evn + vsync_lines; 1007335e3713SNeil Armstrong 1008335e3713SNeil Armstrong writel_relaxed(vs_bline_evn, 1009335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN)); 1010335e3713SNeil Armstrong 1011335e3713SNeil Armstrong writel_relaxed(vs_eline_evn, 1012335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_VSO_ELINE_EVN)); 1013335e3713SNeil Armstrong 1014335e3713SNeil Armstrong writel_relaxed(hs_begin, 1015335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_EVN)); 1016335e3713SNeil Armstrong writel_relaxed(hs_begin, 1017335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_VSO_END_EVN)); 1018335e3713SNeil Armstrong } else { 1019335e3713SNeil Armstrong vs_bline_odd = (de_v_end_odd - 1) 1020335e3713SNeil Armstrong + eof_lines 1021335e3713SNeil Armstrong + vs_adjust; 1022335e3713SNeil Armstrong 1023335e3713SNeil Armstrong writel_relaxed(vs_bline_odd, 1024335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD)); 1025335e3713SNeil Armstrong 1026335e3713SNeil Armstrong writel_relaxed(hs_begin, 1027335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD)); 1028335e3713SNeil Armstrong 1029335e3713SNeil Armstrong if ((vs_bline_odd + vsync_lines) >= lines_f1) { 1030335e3713SNeil Armstrong vs_eline_evn = vs_bline_odd 1031335e3713SNeil Armstrong + vsync_lines 1032335e3713SNeil Armstrong - lines_f1; 1033335e3713SNeil Armstrong 1034335e3713SNeil Armstrong writel_relaxed(vs_eline_evn, priv->io_base 1035335e3713SNeil Armstrong + _REG(ENCI_DVI_VSO_ELINE_EVN)); 1036335e3713SNeil Armstrong 1037335e3713SNeil Armstrong writel_relaxed(hs_begin, priv->io_base 1038335e3713SNeil Armstrong + _REG(ENCI_DVI_VSO_END_EVN)); 1039335e3713SNeil Armstrong } else { 1040335e3713SNeil Armstrong vs_eline_odd = vs_bline_odd 1041335e3713SNeil Armstrong + vsync_lines; 1042335e3713SNeil Armstrong 1043335e3713SNeil Armstrong writel_relaxed(vs_eline_odd, priv->io_base 1044335e3713SNeil Armstrong + _REG(ENCI_DVI_VSO_ELINE_ODD)); 1045335e3713SNeil Armstrong 1046335e3713SNeil Armstrong writel_relaxed(hs_begin, priv->io_base 1047335e3713SNeil Armstrong + _REG(ENCI_DVI_VSO_END_ODD)); 1048335e3713SNeil Armstrong } 1049335e3713SNeil Armstrong } 1050335e3713SNeil Armstrong 1051335e3713SNeil Armstrong /* Program Vsync timing for odd field */ 1052335e3713SNeil Armstrong if (((de_v_end_even - 1) + (eof_lines + 1)) >= lines_f0) { 1053335e3713SNeil Armstrong vs_bline_odd = (de_v_end_even - 1) 1054335e3713SNeil Armstrong + (eof_lines + 1) 1055335e3713SNeil Armstrong - lines_f0; 1056335e3713SNeil Armstrong vs_eline_odd = vs_bline_odd + vsync_lines; 1057335e3713SNeil Armstrong 1058335e3713SNeil Armstrong writel_relaxed(vs_bline_odd, 1059335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD)); 1060335e3713SNeil Armstrong 1061335e3713SNeil Armstrong writel_relaxed(vs_eline_odd, 1062335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_VSO_ELINE_ODD)); 1063335e3713SNeil Armstrong 1064335e3713SNeil Armstrong vso_begin_odd = modulo(hs_begin 1065335e3713SNeil Armstrong + (total_pixels_venc >> 1), 1066335e3713SNeil Armstrong total_pixels_venc); 1067335e3713SNeil Armstrong 1068335e3713SNeil Armstrong writel_relaxed(vso_begin_odd, 1069335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD)); 1070335e3713SNeil Armstrong writel_relaxed(vso_begin_odd, 1071335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_VSO_END_ODD)); 1072335e3713SNeil Armstrong } else { 1073335e3713SNeil Armstrong vs_bline_evn = (de_v_end_even - 1) 1074335e3713SNeil Armstrong + (eof_lines + 1); 1075335e3713SNeil Armstrong 1076335e3713SNeil Armstrong writel_relaxed(vs_bline_evn, 1077335e3713SNeil Armstrong priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN)); 1078335e3713SNeil Armstrong 1079335e3713SNeil Armstrong vso_begin_evn = modulo(hs_begin 1080335e3713SNeil Armstrong + (total_pixels_venc >> 1), 1081335e3713SNeil Armstrong total_pixels_venc); 1082335e3713SNeil Armstrong 1083335e3713SNeil Armstrong writel_relaxed(vso_begin_evn, priv->io_base 1084335e3713SNeil Armstrong + _REG(ENCI_DVI_VSO_BEGIN_EVN)); 1085335e3713SNeil Armstrong 1086335e3713SNeil Armstrong if (vs_bline_evn + vsync_lines >= lines_f0) { 1087335e3713SNeil Armstrong vs_eline_odd = vs_bline_evn 1088335e3713SNeil Armstrong + vsync_lines 1089335e3713SNeil Armstrong - lines_f0; 1090335e3713SNeil Armstrong 1091335e3713SNeil Armstrong writel_relaxed(vs_eline_odd, priv->io_base 1092335e3713SNeil Armstrong + _REG(ENCI_DVI_VSO_ELINE_ODD)); 1093335e3713SNeil Armstrong 1094335e3713SNeil Armstrong writel_relaxed(vso_begin_evn, priv->io_base 1095335e3713SNeil Armstrong + _REG(ENCI_DVI_VSO_END_ODD)); 1096335e3713SNeil Armstrong } else { 1097335e3713SNeil Armstrong vs_eline_evn = vs_bline_evn + vsync_lines; 1098335e3713SNeil Armstrong 1099335e3713SNeil Armstrong writel_relaxed(vs_eline_evn, priv->io_base 1100335e3713SNeil Armstrong + _REG(ENCI_DVI_VSO_ELINE_EVN)); 1101335e3713SNeil Armstrong 1102335e3713SNeil Armstrong writel_relaxed(vso_begin_evn, priv->io_base 1103335e3713SNeil Armstrong + _REG(ENCI_DVI_VSO_END_EVN)); 1104335e3713SNeil Armstrong } 1105335e3713SNeil Armstrong } 1106335e3713SNeil Armstrong } else { 1107335e3713SNeil Armstrong writel_relaxed(vmode->encp.dvi_settings, 1108335e3713SNeil Armstrong priv->io_base + _REG(VENC_DVI_SETTING)); 1109335e3713SNeil Armstrong writel_relaxed(vmode->encp.video_mode, 1110335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_MODE)); 1111335e3713SNeil Armstrong writel_relaxed(vmode->encp.video_mode_adv, 1112335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_MODE_ADV)); 1113335e3713SNeil Armstrong if (vmode->encp.video_prog_mode_present) 1114335e3713SNeil Armstrong writel_relaxed(vmode->encp.video_prog_mode, 1115335e3713SNeil Armstrong priv->io_base + _REG(VENC_VIDEO_PROG_MODE)); 1116335e3713SNeil Armstrong if (vmode->encp.video_sync_mode_present) 1117335e3713SNeil Armstrong writel_relaxed(vmode->encp.video_sync_mode, 1118335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_SYNC_MODE)); 1119335e3713SNeil Armstrong if (vmode->encp.video_yc_dly_present) 1120335e3713SNeil Armstrong writel_relaxed(vmode->encp.video_yc_dly, 1121335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_YC_DLY)); 1122335e3713SNeil Armstrong if (vmode->encp.video_rgb_ctrl_present) 1123335e3713SNeil Armstrong writel_relaxed(vmode->encp.video_rgb_ctrl, 1124335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_RGB_CTRL)); 1125335e3713SNeil Armstrong if (vmode->encp.video_filt_ctrl_present) 1126335e3713SNeil Armstrong writel_relaxed(vmode->encp.video_filt_ctrl, 1127335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_FILT_CTRL)); 1128335e3713SNeil Armstrong if (vmode->encp.video_ofld_voav_ofst_present) 1129335e3713SNeil Armstrong writel_relaxed(vmode->encp.video_ofld_voav_ofst, 1130335e3713SNeil Armstrong priv->io_base 1131335e3713SNeil Armstrong + _REG(ENCP_VIDEO_OFLD_VOAV_OFST)); 1132335e3713SNeil Armstrong writel_relaxed(vmode->encp.yfp1_htime, 1133335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_YFP1_HTIME)); 1134335e3713SNeil Armstrong writel_relaxed(vmode->encp.yfp2_htime, 1135335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_YFP2_HTIME)); 1136335e3713SNeil Armstrong writel_relaxed(vmode->encp.max_pxcnt, 1137335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_MAX_PXCNT)); 1138335e3713SNeil Armstrong writel_relaxed(vmode->encp.hspuls_begin, 1139335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_HSPULS_BEGIN)); 1140335e3713SNeil Armstrong writel_relaxed(vmode->encp.hspuls_end, 1141335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_HSPULS_END)); 1142335e3713SNeil Armstrong writel_relaxed(vmode->encp.hspuls_switch, 1143335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_HSPULS_SWITCH)); 1144335e3713SNeil Armstrong writel_relaxed(vmode->encp.vspuls_begin, 1145335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_VSPULS_BEGIN)); 1146335e3713SNeil Armstrong writel_relaxed(vmode->encp.vspuls_end, 1147335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_VSPULS_END)); 1148335e3713SNeil Armstrong writel_relaxed(vmode->encp.vspuls_bline, 1149335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_VSPULS_BLINE)); 1150335e3713SNeil Armstrong writel_relaxed(vmode->encp.vspuls_eline, 1151335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_VSPULS_ELINE)); 1152335e3713SNeil Armstrong if (vmode->encp.eqpuls_begin_present) 1153335e3713SNeil Armstrong writel_relaxed(vmode->encp.eqpuls_begin, 1154335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_EQPULS_BEGIN)); 1155335e3713SNeil Armstrong if (vmode->encp.eqpuls_end_present) 1156335e3713SNeil Armstrong writel_relaxed(vmode->encp.eqpuls_end, 1157335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_EQPULS_END)); 1158335e3713SNeil Armstrong if (vmode->encp.eqpuls_bline_present) 1159335e3713SNeil Armstrong writel_relaxed(vmode->encp.eqpuls_bline, 1160335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_EQPULS_BLINE)); 1161335e3713SNeil Armstrong if (vmode->encp.eqpuls_eline_present) 1162335e3713SNeil Armstrong writel_relaxed(vmode->encp.eqpuls_eline, 1163335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_EQPULS_ELINE)); 1164335e3713SNeil Armstrong writel_relaxed(vmode->encp.havon_begin, 1165335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_HAVON_BEGIN)); 1166335e3713SNeil Armstrong writel_relaxed(vmode->encp.havon_end, 1167335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_HAVON_END)); 1168335e3713SNeil Armstrong writel_relaxed(vmode->encp.vavon_bline, 1169335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_VAVON_BLINE)); 1170335e3713SNeil Armstrong writel_relaxed(vmode->encp.vavon_eline, 1171335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_VAVON_ELINE)); 1172335e3713SNeil Armstrong writel_relaxed(vmode->encp.hso_begin, 1173335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_HSO_BEGIN)); 1174335e3713SNeil Armstrong writel_relaxed(vmode->encp.hso_end, 1175335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_HSO_END)); 1176335e3713SNeil Armstrong writel_relaxed(vmode->encp.vso_begin, 1177335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_VSO_BEGIN)); 1178335e3713SNeil Armstrong writel_relaxed(vmode->encp.vso_end, 1179335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_VSO_END)); 1180335e3713SNeil Armstrong writel_relaxed(vmode->encp.vso_bline, 1181335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_VSO_BLINE)); 1182335e3713SNeil Armstrong if (vmode->encp.vso_eline_present) 1183335e3713SNeil Armstrong writel_relaxed(vmode->encp.vso_eline, 1184335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_VSO_ELINE)); 1185335e3713SNeil Armstrong if (vmode->encp.sy_val_present) 1186335e3713SNeil Armstrong writel_relaxed(vmode->encp.sy_val, 1187335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_SY_VAL)); 1188335e3713SNeil Armstrong if (vmode->encp.sy2_val_present) 1189335e3713SNeil Armstrong writel_relaxed(vmode->encp.sy2_val, 1190335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_SY2_VAL)); 1191335e3713SNeil Armstrong writel_relaxed(vmode->encp.max_lncnt, 1192335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_MAX_LNCNT)); 1193335e3713SNeil Armstrong 1194335e3713SNeil Armstrong writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); 1195335e3713SNeil Armstrong 1196335e3713SNeil Armstrong /* Set DE signal’s polarity is active high */ 1197335e3713SNeil Armstrong writel_bits_relaxed(BIT(14), BIT(14), 1198335e3713SNeil Armstrong priv->io_base + _REG(ENCP_VIDEO_MODE)); 1199335e3713SNeil Armstrong 1200335e3713SNeil Armstrong /* Program DE timing */ 1201335e3713SNeil Armstrong de_h_begin = modulo(readl_relaxed(priv->io_base + 1202335e3713SNeil Armstrong _REG(ENCP_VIDEO_HAVON_BEGIN)) 1203335e3713SNeil Armstrong + venc_hdmi_latency, 1204335e3713SNeil Armstrong total_pixels_venc); 1205335e3713SNeil Armstrong de_h_end = modulo(de_h_begin + active_pixels_venc, 1206335e3713SNeil Armstrong total_pixels_venc); 1207335e3713SNeil Armstrong 1208335e3713SNeil Armstrong writel_relaxed(de_h_begin, 1209335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DE_H_BEGIN)); 1210335e3713SNeil Armstrong writel_relaxed(de_h_end, 1211335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DE_H_END)); 1212335e3713SNeil Armstrong 1213335e3713SNeil Armstrong /* Program DE timing for even field */ 1214335e3713SNeil Armstrong de_v_begin_even = readl_relaxed(priv->io_base 1215335e3713SNeil Armstrong + _REG(ENCP_VIDEO_VAVON_BLINE)); 1216335e3713SNeil Armstrong if (mode->flags & DRM_MODE_FLAG_INTERLACE) 1217335e3713SNeil Armstrong de_v_end_even = de_v_begin_even + 1218335e3713SNeil Armstrong (mode->vdisplay / 2); 1219335e3713SNeil Armstrong else 1220335e3713SNeil Armstrong de_v_end_even = de_v_begin_even + mode->vdisplay; 1221335e3713SNeil Armstrong 1222335e3713SNeil Armstrong writel_relaxed(de_v_begin_even, 1223335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DE_V_BEGIN_EVEN)); 1224335e3713SNeil Armstrong writel_relaxed(de_v_end_even, 1225335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DE_V_END_EVEN)); 1226335e3713SNeil Armstrong 1227335e3713SNeil Armstrong /* Program DE timing for odd field if needed */ 1228335e3713SNeil Armstrong if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 1229335e3713SNeil Armstrong unsigned int ofld_voav_ofst = 1230335e3713SNeil Armstrong readl_relaxed(priv->io_base + 1231335e3713SNeil Armstrong _REG(ENCP_VIDEO_OFLD_VOAV_OFST)); 1232335e3713SNeil Armstrong de_v_begin_odd = to_signed((ofld_voav_ofst & 0xf0) >> 4) 1233335e3713SNeil Armstrong + de_v_begin_even 1234335e3713SNeil Armstrong + ((mode->vtotal - 1) / 2); 1235335e3713SNeil Armstrong de_v_end_odd = de_v_begin_odd + (mode->vdisplay / 2); 1236335e3713SNeil Armstrong 1237335e3713SNeil Armstrong writel_relaxed(de_v_begin_odd, 1238335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DE_V_BEGIN_ODD)); 1239335e3713SNeil Armstrong writel_relaxed(de_v_end_odd, 1240335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DE_V_END_ODD)); 1241335e3713SNeil Armstrong } 1242335e3713SNeil Armstrong 1243335e3713SNeil Armstrong /* Program Hsync timing */ 1244335e3713SNeil Armstrong if ((de_h_end + front_porch_venc) >= total_pixels_venc) { 1245335e3713SNeil Armstrong hs_begin = de_h_end 1246335e3713SNeil Armstrong + front_porch_venc 1247335e3713SNeil Armstrong - total_pixels_venc; 1248335e3713SNeil Armstrong vs_adjust = 1; 1249335e3713SNeil Armstrong } else { 1250335e3713SNeil Armstrong hs_begin = de_h_end 1251335e3713SNeil Armstrong + front_porch_venc; 1252335e3713SNeil Armstrong vs_adjust = 0; 1253335e3713SNeil Armstrong } 1254335e3713SNeil Armstrong 1255335e3713SNeil Armstrong hs_end = modulo(hs_begin + hsync_pixels_venc, 1256335e3713SNeil Armstrong total_pixels_venc); 1257335e3713SNeil Armstrong 1258335e3713SNeil Armstrong writel_relaxed(hs_begin, 1259335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DVI_HSO_BEGIN)); 1260335e3713SNeil Armstrong writel_relaxed(hs_end, 1261335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DVI_HSO_END)); 1262335e3713SNeil Armstrong 1263335e3713SNeil Armstrong /* Program Vsync timing for even field */ 1264335e3713SNeil Armstrong if (de_v_begin_even >= 1265335e3713SNeil Armstrong (sof_lines + vsync_lines + (1 - vs_adjust))) 1266335e3713SNeil Armstrong vs_bline_evn = de_v_begin_even 1267335e3713SNeil Armstrong - sof_lines 1268335e3713SNeil Armstrong - vsync_lines 1269335e3713SNeil Armstrong - (1 - vs_adjust); 1270335e3713SNeil Armstrong else 1271335e3713SNeil Armstrong vs_bline_evn = mode->vtotal 1272335e3713SNeil Armstrong + de_v_begin_even 1273335e3713SNeil Armstrong - sof_lines 1274335e3713SNeil Armstrong - vsync_lines 1275335e3713SNeil Armstrong - (1 - vs_adjust); 1276335e3713SNeil Armstrong 1277335e3713SNeil Armstrong vs_eline_evn = modulo(vs_bline_evn + vsync_lines, 1278335e3713SNeil Armstrong mode->vtotal); 1279335e3713SNeil Armstrong 1280335e3713SNeil Armstrong writel_relaxed(vs_bline_evn, 1281335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DVI_VSO_BLINE_EVN)); 1282335e3713SNeil Armstrong writel_relaxed(vs_eline_evn, 1283335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DVI_VSO_ELINE_EVN)); 1284335e3713SNeil Armstrong 1285335e3713SNeil Armstrong vso_begin_evn = hs_begin; 1286335e3713SNeil Armstrong writel_relaxed(vso_begin_evn, 1287335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_EVN)); 1288335e3713SNeil Armstrong writel_relaxed(vso_begin_evn, 1289335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DVI_VSO_END_EVN)); 1290335e3713SNeil Armstrong 1291335e3713SNeil Armstrong /* Program Vsync timing for odd field if needed */ 1292335e3713SNeil Armstrong if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 1293335e3713SNeil Armstrong vs_bline_odd = (de_v_begin_odd - 1) 1294335e3713SNeil Armstrong - sof_lines 1295335e3713SNeil Armstrong - vsync_lines; 1296335e3713SNeil Armstrong vs_eline_odd = (de_v_begin_odd - 1) 1297335e3713SNeil Armstrong - vsync_lines; 1298335e3713SNeil Armstrong vso_begin_odd = modulo(hs_begin 1299335e3713SNeil Armstrong + (total_pixels_venc >> 1), 1300335e3713SNeil Armstrong total_pixels_venc); 1301335e3713SNeil Armstrong 1302335e3713SNeil Armstrong writel_relaxed(vs_bline_odd, 1303335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DVI_VSO_BLINE_ODD)); 1304335e3713SNeil Armstrong writel_relaxed(vs_eline_odd, 1305335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DVI_VSO_ELINE_ODD)); 1306335e3713SNeil Armstrong writel_relaxed(vso_begin_odd, 1307335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_ODD)); 1308335e3713SNeil Armstrong writel_relaxed(vso_begin_odd, 1309335e3713SNeil Armstrong priv->io_base + _REG(ENCP_DVI_VSO_END_ODD)); 1310335e3713SNeil Armstrong } 1311335e3713SNeil Armstrong 1312335e3713SNeil Armstrong /* Select ENCP for VIU */ 1313335e3713SNeil Armstrong meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCP); 1314335e3713SNeil Armstrong } 1315335e3713SNeil Armstrong 1316335e3713SNeil Armstrong writel_relaxed((use_enci ? 1 : 2) | 1317335e3713SNeil Armstrong (mode->flags & DRM_MODE_FLAG_PHSYNC ? 1 << 2 : 0) | 1318335e3713SNeil Armstrong (mode->flags & DRM_MODE_FLAG_PVSYNC ? 1 << 3 : 0) | 1319335e3713SNeil Armstrong 4 << 5 | 1320335e3713SNeil Armstrong (venc_repeat ? 1 << 8 : 0) | 1321335e3713SNeil Armstrong (hdmi_repeat ? 1 << 12 : 0), 1322335e3713SNeil Armstrong priv->io_base + _REG(VPU_HDMI_SETTING)); 1323335e3713SNeil Armstrong 1324335e3713SNeil Armstrong priv->venc.hdmi_repeat = hdmi_repeat; 1325335e3713SNeil Armstrong priv->venc.venc_repeat = venc_repeat; 1326335e3713SNeil Armstrong priv->venc.hdmi_use_enci = use_enci; 1327335e3713SNeil Armstrong 1328335e3713SNeil Armstrong priv->venc.current_mode = MESON_VENC_MODE_HDMI; 1329335e3713SNeil Armstrong } 1330335e3713SNeil Armstrong EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set); 1331335e3713SNeil Armstrong 1332bbbe775eSNeil Armstrong void meson_venci_cvbs_mode_set(struct meson_drm *priv, 1333bbbe775eSNeil Armstrong struct meson_cvbs_enci_mode *mode) 1334bbbe775eSNeil Armstrong { 1335bbbe775eSNeil Armstrong if (mode->mode_tag == priv->venc.current_mode) 1336bbbe775eSNeil Armstrong return; 1337bbbe775eSNeil Armstrong 1338bbbe775eSNeil Armstrong /* CVBS Filter settings */ 1339bbbe775eSNeil Armstrong writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL)); 1340bbbe775eSNeil Armstrong writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2)); 1341bbbe775eSNeil Armstrong 1342bbbe775eSNeil Armstrong /* Digital Video Select : Interlace, clk27 clk, external */ 1343bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING)); 1344bbbe775eSNeil Armstrong 1345bbbe775eSNeil Armstrong /* Reset Video Mode */ 1346bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE)); 1347bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); 1348bbbe775eSNeil Armstrong 1349bbbe775eSNeil Armstrong /* Horizontal sync signal output */ 1350bbbe775eSNeil Armstrong writel_relaxed(mode->hso_begin, 1351bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN)); 1352bbbe775eSNeil Armstrong writel_relaxed(mode->hso_end, 1353bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_SYNC_HSO_END)); 1354bbbe775eSNeil Armstrong 1355bbbe775eSNeil Armstrong /* Vertical Sync lines */ 1356bbbe775eSNeil Armstrong writel_relaxed(mode->vso_even, 1357bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN)); 1358bbbe775eSNeil Armstrong writel_relaxed(mode->vso_odd, 1359bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN)); 1360bbbe775eSNeil Armstrong 1361bbbe775eSNeil Armstrong /* Macrovision max amplitude change */ 1362bbbe775eSNeil Armstrong writel_relaxed(0x8100 + mode->macv_max_amp, 1363bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_MACV_MAX_AMP)); 1364bbbe775eSNeil Armstrong 1365bbbe775eSNeil Armstrong /* Video mode */ 1366bbbe775eSNeil Armstrong writel_relaxed(mode->video_prog_mode, 1367bbbe775eSNeil Armstrong priv->io_base + _REG(VENC_VIDEO_PROG_MODE)); 1368bbbe775eSNeil Armstrong writel_relaxed(mode->video_mode, 1369bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_VIDEO_MODE)); 1370bbbe775eSNeil Armstrong 1371bbbe775eSNeil Armstrong /* Advanced Video Mode : 1372bbbe775eSNeil Armstrong * Demux shifting 0x2 1373bbbe775eSNeil Armstrong * Blank line end at line17/22 1374bbbe775eSNeil Armstrong * High bandwidth Luma Filter 1375bbbe775eSNeil Armstrong * Low bandwidth Chroma Filter 1376bbbe775eSNeil Armstrong * Bypass luma low pass filter 1377bbbe775eSNeil Armstrong * No macrovision on CSYNC 1378bbbe775eSNeil Armstrong */ 1379bbbe775eSNeil Armstrong writel_relaxed(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); 1380bbbe775eSNeil Armstrong 1381bbbe775eSNeil Armstrong writel(mode->sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH)); 1382bbbe775eSNeil Armstrong 1383bbbe775eSNeil Armstrong /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */ 1384bbbe775eSNeil Armstrong writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE)); 1385bbbe775eSNeil Armstrong 1386bbbe775eSNeil Armstrong /* 0x3 Y, C, and Component Y delay */ 1387bbbe775eSNeil Armstrong writel_relaxed(mode->yc_delay, priv->io_base + _REG(ENCI_YC_DELAY)); 1388bbbe775eSNeil Armstrong 1389bbbe775eSNeil Armstrong /* Timings */ 1390bbbe775eSNeil Armstrong writel_relaxed(mode->pixel_start, 1391bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START)); 1392bbbe775eSNeil Armstrong writel_relaxed(mode->pixel_end, 1393bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END)); 1394bbbe775eSNeil Armstrong 1395bbbe775eSNeil Armstrong writel_relaxed(mode->top_field_line_start, 1396bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START)); 1397bbbe775eSNeil Armstrong writel_relaxed(mode->top_field_line_end, 1398bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END)); 1399bbbe775eSNeil Armstrong 1400bbbe775eSNeil Armstrong writel_relaxed(mode->bottom_field_line_start, 1401bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START)); 1402bbbe775eSNeil Armstrong writel_relaxed(mode->bottom_field_line_end, 1403bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END)); 1404bbbe775eSNeil Armstrong 1405bbbe775eSNeil Armstrong /* Internal Venc, Internal VIU Sync, Internal Vencoder */ 1406bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VENC_SYNC_ROUTE)); 1407bbbe775eSNeil Armstrong 1408bbbe775eSNeil Armstrong /* UNreset Interlaced TV Encoder */ 1409bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST)); 1410bbbe775eSNeil Armstrong 1411bbbe775eSNeil Armstrong /* Enable Vfifo2vd, Y_Cb_Y_Cr select */ 1412bbbe775eSNeil Armstrong writel_relaxed(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); 1413bbbe775eSNeil Armstrong 1414bbbe775eSNeil Armstrong /* Power UP Dacs */ 1415bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_SETTING)); 1416bbbe775eSNeil Armstrong 1417bbbe775eSNeil Armstrong /* Video Upsampling */ 1418bbbe775eSNeil Armstrong writel_relaxed(0x0061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL0)); 1419bbbe775eSNeil Armstrong writel_relaxed(0x4061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL1)); 1420bbbe775eSNeil Armstrong writel_relaxed(0x5061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL2)); 1421bbbe775eSNeil Armstrong 1422bbbe775eSNeil Armstrong /* Select Interlace Y DACs */ 1423bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL0)); 1424bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL1)); 1425bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL2)); 1426bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL3)); 1427bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL4)); 1428bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL5)); 1429bbbe775eSNeil Armstrong 1430bbbe775eSNeil Armstrong /* Select ENCI for VIU */ 1431bbbe775eSNeil Armstrong meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI); 1432bbbe775eSNeil Armstrong 1433bbbe775eSNeil Armstrong /* Enable ENCI FIFO */ 1434bbbe775eSNeil Armstrong writel_relaxed(0x2000, priv->io_base + _REG(VENC_VDAC_FIFO_CTRL)); 1435bbbe775eSNeil Armstrong 1436bbbe775eSNeil Armstrong /* Select ENCI DACs 0, 1, 4, and 5 */ 1437bbbe775eSNeil Armstrong writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_0)); 1438bbbe775eSNeil Armstrong writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_1)); 1439bbbe775eSNeil Armstrong 1440bbbe775eSNeil Armstrong /* Interlace video enable */ 1441bbbe775eSNeil Armstrong writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); 1442bbbe775eSNeil Armstrong 1443bbbe775eSNeil Armstrong /* Configure Video Saturation / Contrast / Brightness / Hue */ 1444bbbe775eSNeil Armstrong writel_relaxed(mode->video_saturation, 1445bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_VIDEO_SAT)); 1446bbbe775eSNeil Armstrong writel_relaxed(mode->video_contrast, 1447bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_VIDEO_CONT)); 1448bbbe775eSNeil Armstrong writel_relaxed(mode->video_brightness, 1449bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_VIDEO_BRIGHT)); 1450bbbe775eSNeil Armstrong writel_relaxed(mode->video_hue, 1451bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_VIDEO_HUE)); 1452bbbe775eSNeil Armstrong 1453bbbe775eSNeil Armstrong /* Enable DAC0 Filter */ 1454bbbe775eSNeil Armstrong writel_relaxed(0x1, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0)); 1455bbbe775eSNeil Armstrong writel_relaxed(0xfc48, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL1)); 1456bbbe775eSNeil Armstrong 1457bbbe775eSNeil Armstrong /* 0 in Macrovision register 0 */ 1458bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(ENCI_MACV_N0)); 1459bbbe775eSNeil Armstrong 1460bbbe775eSNeil Armstrong /* Analog Synchronization and color burst value adjust */ 1461bbbe775eSNeil Armstrong writel_relaxed(mode->analog_sync_adj, 1462bbbe775eSNeil Armstrong priv->io_base + _REG(ENCI_SYNC_ADJ)); 1463bbbe775eSNeil Armstrong 1464bbbe775eSNeil Armstrong priv->venc.current_mode = mode->mode_tag; 1465bbbe775eSNeil Armstrong } 1466bbbe775eSNeil Armstrong 1467bbbe775eSNeil Armstrong /* Returns the current ENCI field polarity */ 1468bbbe775eSNeil Armstrong unsigned int meson_venci_get_field(struct meson_drm *priv) 1469bbbe775eSNeil Armstrong { 1470bbbe775eSNeil Armstrong return readl_relaxed(priv->io_base + _REG(ENCI_INFO_READ)) & BIT(29); 1471bbbe775eSNeil Armstrong } 1472bbbe775eSNeil Armstrong 1473bbbe775eSNeil Armstrong void meson_venc_enable_vsync(struct meson_drm *priv) 1474bbbe775eSNeil Armstrong { 1475bbbe775eSNeil Armstrong writel_relaxed(2, priv->io_base + _REG(VENC_INTCTRL)); 1476bbbe775eSNeil Armstrong } 1477bbbe775eSNeil Armstrong 1478bbbe775eSNeil Armstrong void meson_venc_disable_vsync(struct meson_drm *priv) 1479bbbe775eSNeil Armstrong { 1480bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL)); 1481bbbe775eSNeil Armstrong } 1482bbbe775eSNeil Armstrong 1483bbbe775eSNeil Armstrong void meson_venc_init(struct meson_drm *priv) 1484bbbe775eSNeil Armstrong { 14850c931a29SNeil Armstrong /* Disable CVBS VDAC */ 14860c931a29SNeil Armstrong regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0); 14870c931a29SNeil Armstrong regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8); 14880c931a29SNeil Armstrong 14890c931a29SNeil Armstrong /* Power Down Dacs */ 14900c931a29SNeil Armstrong writel_relaxed(0xff, priv->io_base + _REG(VENC_VDAC_SETTING)); 14910c931a29SNeil Armstrong 14920c931a29SNeil Armstrong /* Disable HDMI PHY */ 14930c931a29SNeil Armstrong regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0); 14940c931a29SNeil Armstrong 14950c931a29SNeil Armstrong /* Disable HDMI */ 14960c931a29SNeil Armstrong writel_bits_relaxed(0x3, 0, 14970c931a29SNeil Armstrong priv->io_base + _REG(VPU_HDMI_SETTING)); 14980c931a29SNeil Armstrong 1499bbbe775eSNeil Armstrong /* Disable all encoders */ 1500bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); 1501bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); 1502bbbe775eSNeil Armstrong writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN)); 1503bbbe775eSNeil Armstrong 1504bbbe775eSNeil Armstrong /* Disable VSync IRQ */ 1505bbbe775eSNeil Armstrong meson_venc_disable_vsync(priv); 1506bbbe775eSNeil Armstrong 1507bbbe775eSNeil Armstrong priv->venc.current_mode = MESON_VENC_MODE_NONE; 1508bbbe775eSNeil Armstrong } 1509