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