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