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