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